- numPiecesSpanned := fileEndPieceIndex - fileFirstPieceIndex
- switch numPiecesSpanned {
- case 0:
- case 1:
- if !torrentCompletedPieces.Contains(bitmap.BitIndex(fileFirstPieceIndex)) {
- left += fileLength
- }
- default:
- if !torrentCompletedPieces.Contains(bitmap.BitIndex(fileFirstPieceIndex)) {
- left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize)
- }
- if !torrentCompletedPieces.Contains(bitmap.BitIndex(fileEndPieceIndex - 1)) {
- left += fileTorrentOffset + fileLength - int64(fileEndPieceIndex-1)*torrentUsualPieceSize
+ if fileLength == 0 {
+ return
+ }
+
+ noCompletedMiddlePieces := roaring.New()
+ noCompletedMiddlePieces.AddRange(bitmap.BitRange(fileFirstPieceIndex), bitmap.BitRange(fileEndPieceIndex))
+ noCompletedMiddlePieces.AndNot(torrentCompletedPieces)
+ noCompletedMiddlePieces.Iterate(func(pieceIndex uint32) bool {
+ i := int(pieceIndex)
+ pieceSizeCompleted := pieceSizeCompletedFn(i)
+ if i == fileFirstPieceIndex {
+ beginOffset := fileTorrentOffset % torrentUsualPieceSize
+ beginSize := torrentUsualPieceSize - beginOffset
+ beginDownLoaded := pieceSizeCompleted - beginOffset
+ if beginDownLoaded < 0 {
+ beginDownLoaded = 0
+ }
+ left += beginSize - beginDownLoaded
+ } else if i == fileEndPieceIndex-1 {
+ endSize := (fileTorrentOffset + fileLength) % torrentUsualPieceSize
+ if endSize == 0 {
+ endSize = torrentUsualPieceSize
+ }
+ endDownloaded := pieceSizeCompleted
+ if endDownloaded > endSize {
+ endDownloaded = endSize
+ }
+ left += endSize - endDownloaded
+ } else {
+ left += torrentUsualPieceSize - pieceSizeCompleted