-- todo - map with index to a new data structure (peers who have that piece amd state)
data PieceData = PieceData { peers :: [Peer] -- ^ list of peers who have this piece
, state :: PieceDlState -- ^ state of the piece from download perspective.
- , hash :: ByteString } -- ^ piece hash
+ , 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.
-mkPieceMap :: Integer -> ByteString -> PieceMap
-mkPieceMap numPieces pieceHash = fromList kvs
+mkPieceMap :: Integer -> ByteString -> Integer -> PieceMap
+mkPieceMap numPieces pieceHash pLen = fromList kvs
where kvs = [(i, PieceData { peers = []
, state = Pending
- , hash = h }) | (i, h) <- zip [0..numPieces] hashes]
+ , hash = h
+ , len = pLen })
+ | (i, h) <- zip [0..numPieces] hashes]
hashes = splitN (fromIntegral numPieces) pieceHash
havePiece :: PieceMap -> Integer -> Bool
case pickPiece pieceStatus of
Nothing -> putStrLn "Nothing to download"
Just workPiece -> do
- sendMsg (handle state) (RequestMsg workPiece 0 16384)
+ let pLen = len (pieceStatus ! workPiece)
+ sendMsg (handle state) (RequestMsg workPiece 0 pLen)
putStrLn $ "--> RequestMsg for Piece " ++ (show workPiece) ++ "to peer: " ++ show (peer state)
msg <- getMsg (handle state)
putStrLn $ "<-- " ++ show msg ++ "from peer: " ++ show (peer state)
, heChoking = True
, meInterested = False
, meChoking = True }
- pieceHash = (pieces (info m))
+ pieceHash = pieces (info m)
numPieces = (toInteger . (`quot` 20) . BC.length) pieceHash
- pieceStatus = mkPieceMap numPieces pieceHash
+ pLen = pieceLength (info m) :: Integer
+ pieceStatus = mkPieceMap numPieces pieceHash pLen
msgLoop state pieceStatus