module System.TPFS.Header (Header(..), getHeader, putHeader, headerSize) where
import Control.Applicative
import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import System.TPFS.Device
data Header = Header { fileOffset :: Address
, maxFiles :: Word64
, tagOffset :: Address
, maxTags :: Word64
, superBlockMap :: Address
, blockMap :: Address
, blockOffset :: Address
, blockSize :: Word64
, maxBlocks :: Word64
}
deriving (Read, Show, Eq, Ord)
headerSize = 80
instance Binary Header where
get = do get :: Get Magic
Header <$> getWord64le
<*> getWord64le
<*> getWord64le
<*> getWord64le
<*> getWord64le
<*> getWord64le
<*> getWord64le
<*> getWord64le
<*> getWord64le
put hdr = do put $ Magic
putWord64le $ fileOffset hdr
putWord64le $ maxFiles hdr
putWord64le $ tagOffset hdr
putWord64le $ maxFiles hdr
putWord64le $ superBlockMap hdr
putWord64le $ blockMap hdr
putWord64le $ blockOffset hdr
putWord64le $ blockSize hdr
putWord64le $ maxBlocks hdr
getHeader :: Device m h => h -> m Header
getHeader h = decode <$> dGet h 0 headerSize
putHeader :: Device m h => h -> Header -> m ()
putHeader h = dPut h 0 . encode
data Magic = Magic
instance Binary Magic where
get = do m <- mapM (const getWord8) [1..8]
case map (toEnum.fromEnum) m of
"TPFS0000" -> return Magic
_ -> fail "Invalid header."
put Magic = mapM_ (putWord8.toEnum.fromEnum) "TPFS0000"