From: Matt Joiner <anacrolix@gmail.com>
Date: Tue, 24 Mar 2020 00:19:11 +0000 (+1100)
Subject: Add abstraction and tests for #387
X-Git-Tag: v1.15.0~5
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=3507ff1a69fd0fecee89be8536ef3dd8b3ffca4d;p=btrtrc.git

Add abstraction and tests for #387
---

diff --git a/file.go b/file.go
index b9548eba..167948be 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,15 +65,19 @@ func (f *File) bytesLeft() (left int64) {
 		}
 		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
 // single-file torrent.
 func (f *File) DisplayPath() string {
diff --git a/file_test.go b/file_test.go
index b66d1985..b4111268 100644
--- a/file_test.go
+++ b/file_test.go
@@ -3,6 +3,7 @@ package torrent
 import (
 	"testing"
 
+	"github.com/anacrolix/missinggo/v2/bitmap"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -20,3 +21,51 @@ func TestFileExclusivePieces(t *testing.T) {
 		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)
+}