-data PieceDlState = Pending
- | Downloading
- | Have
- deriving (Show, Eq)
-
--- todo - map with index to a new data structure (peers who have that piece and state)
-data PieceData = PieceData { peers :: [Peer] -- ^ list of peers who have this piece
- , dlstate :: PieceDlState -- ^ state of the piece from download perspective.
- , hash :: ByteString -- ^ piece hash
- , len :: Integer } -- ^ piece length
-
--- which piece is with which peers
-type PieceMap = Map Integer PieceData
-
-
--- Make the initial Piece map, with the assumption that no peer has the
--- piece and that every piece is pending download.
-initPieceMap :: ByteString -> Integer -> Integer -> PieceMap
-initPieceMap pieceHash fileLen pieceLen = fromList kvs
- where
- numPieces = (toInteger . (`quot` 20) . BC.length) pieceHash
- kvs = [(i, PieceData { peers = []
- , dlstate = Pending
- , hash = h
- , len = pLen })
- | (i, h, pLen) <- zip3 [0..numPieces] hashes pLengths]
- hashes = splitN 20 pieceHash
- pLengths = splitNum fileLen pieceLen
-
-pieceMapFromFile :: FilePath -> PieceMap -> IO PieceMap
-pieceMapFromFile filePath pieceMap =
- traverseWithKey f pieceMap
- where
- f k v = do
- let offset = if k == 0 then 0 else k * len (pieceMap ! (k - 1))
- isHashValid <- flip verifyHash (hash v) <$> readFileAtOffset filePath offset (len v)
- if isHashValid
- then return $ v { dlstate = Have }
- else return v
-