-- | Saving/loading with serialization and compression. module Game.LambdaHack.Utils.File ( encodeEOF, strictDecodeEOF ) where import System.IO import Data.Binary import qualified Data.ByteString.Lazy as LBS import qualified Codec.Compression.Zlib as Z -- | Serialize, compress and save data. -- Note that LBS.writeFile opens the file in binary mode. encodeData :: Binary a => FilePath -> a -> IO () encodeData f = LBS.writeFile f . Z.compress . encode -- | Serialize, compress and save data with an EOF marker. -- The @OK@ is used as an EOF marker to ensure any apparent problems with -- corrupted files are reported to the user ASAP. encodeEOF :: Binary a => FilePath -> a -> IO () encodeEOF f a = encodeData f (a, "OK") -- | Read and decompress the serialized data. strictReadSerialized :: FilePath -> IO LBS.ByteString strictReadSerialized f = withBinaryFile f ReadMode $ \ h -> do c <- LBS.hGetContents h let d = Z.decompress c LBS.length d `seq` return d -- | Read, decompress and deserialize data. strictDecodeData :: Binary a => FilePath -> IO a strictDecodeData = fmap decode . strictReadSerialized -- | Read, decompress and deserialize data with an EOF marker. -- The @OK@ EOF marker ensures any easily detectable file corruption -- is discovered and reported before the function returns. strictDecodeEOF :: Binary a => FilePath -> IO a strictDecodeEOF f = do (a, n) <- strictDecodeData f if n == "OK" then return a else error $ "Fatal error: corrupted file " ++ f