file.go | 20 +++++++++++--------- file_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/file.go b/file.go index b9548ebae87a2d0b51fe487315a63e1d8c0ddcb3..167948be15dd142cada7c5315adf5880776a5226 100644 --- a/file.go +++ b/file.go @@ -54,11 +54,9 @@ func (f *File) bytesCompleted() int64 { return f.length - f.bytesLeft() } -func (f *File) bytesLeft() (left int64) { - pieceSize := int64(f.t.usualPieceSize()) - firstPieceIndex := f.firstPieceIndex() - endPieceIndex := f.endPieceIndex() - 1 - bitmap.Flip(f.t._completedPieces, firstPieceIndex+1, endPieceIndex).IterTyped(func(piece int) bool { +func fileBytesLeft(pieceSize int64, firstPieceIndex int, endPieceIndex int, fileOffset int64, fileLength int64, completedPieces bitmap.Bitmap) (left int64) { + endPieceIndex-- + bitmap.Flip(completedPieces, firstPieceIndex+1, endPieceIndex).IterTyped(func(piece int) bool { if piece >= endPieceIndex { return false } @@ -67,13 +65,17 @@ left += pieceSize } return true }) - if !f.t.pieceComplete(firstPieceIndex) { - left += pieceSize - (f.offset % pieceSize) + if !completedPieces.Get(firstPieceIndex) { + left += pieceSize - (fileOffset % pieceSize) } - if !f.t.pieceComplete(endPieceIndex) { - left += (f.offset + f.length) % pieceSize + if !completedPieces.Get(endPieceIndex) { + left += (fileOffset + fileLength) % pieceSize } return +} + +func (f *File) bytesLeft() (left int64) { + return fileBytesLeft(int64(f.t.usualPieceSize()), f.firstPieceIndex(), f.endPieceIndex(), f.offset, f.length, f.t._completedPieces) } // The relative file path for a multi-file torrent, and the torrent name for a diff --git a/file_test.go b/file_test.go index b66d198529fe46390a83b557c7251a58bf62362c..b411126808ba922e8f48a4dcfa65cc59727e613a 100644 --- a/file_test.go +++ b/file_test.go @@ -3,6 +3,7 @@ import ( "testing" + "github.com/anacrolix/missinggo/v2/bitmap" "github.com/stretchr/testify/assert" ) @@ -20,3 +21,51 @@ assert.EqualValues(t, _case.begin, begin) assert.EqualValues(t, _case.end, end) } } + +type testFileBytesLeft struct { + usualPieceSize int64 + firstPieceIndex int + endPieceIndex int + fileOffset int64 + fileLength int64 + completedPieces bitmap.Bitmap + expected int64 + name string +} + +func (me testFileBytesLeft) Run(t *testing.T) { + t.Run(me.name, func(t *testing.T) { + assert.EqualValues(t, me.expected, fileBytesLeft(me.usualPieceSize, me.firstPieceIndex, me.endPieceIndex, me.fileOffset, me.fileLength, me.completedPieces)) + }) +} + +func TestFileBytesLeft(t *testing.T) { + testFileBytesLeft{ + usualPieceSize: 2, + firstPieceIndex: 1, + endPieceIndex: 1, + fileOffset: 1, + fileLength: 1, + expected: 1, + }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 0, + endPieceIndex: 0, + fileOffset: 1, + fileLength: 1, + expected: 1, + name: "FileInFirstPiece", + }.Run(t) + + testFileBytesLeft{ + usualPieceSize: 3, + firstPieceIndex: 0, + endPieceIndex: 0, + fileOffset: 1, + fileLength: 1, + expected: 1, + name: "LandLocked", + }.Run(t) +}