module Octane.Type.RawReplay
( RawReplay(..)
, newRawReplay
) where
import qualified Control.DeepSeq as DeepSeq
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 LazyBytes
import qualified GHC.Generics as Generics
import qualified Octane.Utility.CRC as CRC
import qualified Octane.Type.Word32 as Word32
import qualified Text.Printf as Printf
data RawReplay = RawReplay
{ headerSize :: Word32.Word32
, headerCRC :: Word32.Word32
, header :: LazyBytes.ByteString
, contentSize :: Word32.Word32
, contentCRC :: Word32.Word32
, content :: LazyBytes.ByteString
, footer :: LazyBytes.ByteString
} deriving (Eq, Generics.Generic, Show)
instance Binary.Binary RawReplay where
get = do
headerSize <- Binary.get
headerCRC <- Binary.get
header <- Binary.getLazyByteString (Word32.fromWord32 headerSize)
checkCRC headerCRC header
contentSize <- Binary.get
contentCRC <- Binary.get
content <- Binary.getLazyByteString (Word32.fromWord32 contentSize)
checkCRC contentCRC content
footer <- Binary.getRemainingLazyByteString
pure RawReplay { .. }
put replay = do
Binary.put (headerSize replay)
Binary.put (headerCRC replay)
Binary.putLazyByteString (header replay)
Binary.put (contentSize replay)
Binary.put (contentCRC replay)
Binary.putLazyByteString (content replay)
Binary.putLazyByteString (footer replay)
instance DeepSeq.NFData RawReplay where
newRawReplay
:: LazyBytes.ByteString
-> LazyBytes.ByteString
-> LazyBytes.ByteString
-> RawReplay
newRawReplay header content footer = do
let headerSize = Word32.toWord32 (LazyBytes.length header)
let headerCRC = Word32.Word32 (CRC.crc32 header)
let contentSize = Word32.toWord32 (LazyBytes.length content)
let contentCRC = Word32.Word32 (CRC.crc32 content)
RawReplay { .. }
checkCRC :: (Monad m) => Word32.Word32 -> LazyBytes.ByteString -> m ()
checkCRC (Word32.Word32 expected) bytes = do
let actual = CRC.crc32 bytes
Monad.when (actual /= expected) (do
let message = Printf.printf
"CRC 0x%08x does not equal expected value 0x%08x"
actual
expected
fail message)