file.go | 29 ++++++++++++++++------------- file_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- diff --git a/file.go b/file.go index 1c54f20c610d621301c9a826643a455d64cf7a85..f02424000971f46f65583864c7fd1809aac8b841 100644 --- a/file.go +++ b/file.go @@ -62,21 +62,24 @@ fileTorrentOffset int64, fileLength int64, torrentCompletedPieces bitmap.Bitmap, ) (left int64) { - fileEndPieceIndex-- - bitmap.Flip(torrentCompletedPieces, fileFirstPieceIndex+1, fileEndPieceIndex).IterTyped(func(piece int) bool { - if piece >= fileEndPieceIndex { - return false + numPiecesSpanned := fileEndPieceIndex - fileFirstPieceIndex + switch numPiecesSpanned { + case 0: + case 1: + if !torrentCompletedPieces.Get(fileFirstPieceIndex) { + left += fileLength + } + default: + if !torrentCompletedPieces.Get(fileFirstPieceIndex) { + left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize) } - if piece > fileFirstPieceIndex { - left += torrentUsualPieceSize + if !torrentCompletedPieces.Get(fileEndPieceIndex - 1) { + left += fileTorrentOffset + fileLength - int64(fileEndPieceIndex-1)*torrentUsualPieceSize } - return true - }) - if !torrentCompletedPieces.Get(fileFirstPieceIndex) { - left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize) - } - if !torrentCompletedPieces.Get(fileEndPieceIndex) { - left += (fileTorrentOffset + fileLength) % torrentUsualPieceSize + completedMiddlePieces := torrentCompletedPieces.Copy() + completedMiddlePieces.RemoveRange(0, fileFirstPieceIndex+1) + completedMiddlePieces.RemoveRange(fileEndPieceIndex-1, bitmap.ToEnd) + left += int64(numPiecesSpanned-2-completedMiddlePieces.Len()) * torrentUsualPieceSize } return } diff --git a/file_test.go b/file_test.go index b411126808ba922e8f48a4dcfa65cc59727e613a..0443cf3bd5cc63a9e9766f45a9d4a489f709c43f 100644 --- a/file_test.go +++ b/file_test.go @@ -40,19 +40,31 @@ }) } func TestFileBytesLeft(t *testing.T) { + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 1, + endPieceIndex: 1, + fileOffset: 1, + fileLength: 0, + expected: 0, + name: "ZeroLengthFile", + }.Run(t) + testFileBytesLeft{ usualPieceSize: 2, firstPieceIndex: 1, - endPieceIndex: 1, + endPieceIndex: 2, fileOffset: 1, fileLength: 1, expected: 1, + name: "EndOfSecondPiece", }.Run(t) testFileBytesLeft{ usualPieceSize: 3, firstPieceIndex: 0, - endPieceIndex: 0, + endPieceIndex: 1, fileOffset: 1, fileLength: 1, expected: 1, @@ -62,10 +74,44 @@ testFileBytesLeft{ usualPieceSize: 3, firstPieceIndex: 0, - endPieceIndex: 0, + endPieceIndex: 1, fileOffset: 1, fileLength: 1, expected: 1, name: "LandLocked", + }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 1, + endPieceIndex: 3, + fileOffset: 4, + fileLength: 4, + expected: 4, + name: "TwoPieces", + }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 1, + endPieceIndex: 4, + fileOffset: 5, + fileLength: 7, + expected: 7, + name: "ThreePieces", + }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 1, + endPieceIndex: 4, + fileOffset: 5, + fileLength: 7, + expected: 0, + completedPieces: func() (ret bitmap.Bitmap) { + ret.AddRange(0, 5) + return + }(), + name: "ThreePiecesCompletedAll", }.Run(t) }