Add BytesCompleted method for files (#347)
* Add BytesCompleted method for files * Make sure we check limit pieces correctly * Remove unnecessary info check
This commit is contained in:
parent
da2d174fc9
commit
f22acca804
43
file.go
43
file.go
|
@ -3,7 +3,10 @@ package torrent
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/anacrolix/missinggo/bitmap"
|
||||||
|
|
||||||
"github.com/anacrolix/torrent/metainfo"
|
"github.com/anacrolix/torrent/metainfo"
|
||||||
|
pp "github.com/anacrolix/torrent/peer_protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Provides access to regions of torrent data that correspond to its files.
|
// Provides access to regions of torrent data that correspond to its files.
|
||||||
|
@ -40,6 +43,46 @@ func (f *File) Length() int64 {
|
||||||
return f.length
|
return f.length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Number of bytes of the entire file we have completed. This is the sum of
|
||||||
|
// completed pieces, and dirtied chunks of incomplete pieces.
|
||||||
|
func (f *File) BytesCompleted() int64 {
|
||||||
|
f.t.cl.rLock()
|
||||||
|
defer f.t.cl.rUnlock()
|
||||||
|
return f.bytesCompleted()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) bytesCompleted() int64 {
|
||||||
|
return f.length - f.bytesLeft()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) bytesLeft() (left int64) {
|
||||||
|
firstPieceIndex := f.firstPieceIndex()
|
||||||
|
endPieceIndex := f.endPieceIndex()
|
||||||
|
bitmap.Flip(f.t.completedPieces, firstPieceIndex, endPieceIndex+1).IterTyped(func(piece int) bool {
|
||||||
|
p := &f.t.pieces[piece]
|
||||||
|
left += int64(p.length() - p.numDirtyBytes())
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
startPiece := f.t.piece(firstPieceIndex)
|
||||||
|
endChunk := int(f.offset%f.t.info.PieceLength) * int(startPiece.numChunks()) / int(startPiece.length())
|
||||||
|
bitmap.Flip(startPiece.dirtyChunks, 0, endChunk).IterTyped(func(chunk int) bool {
|
||||||
|
left -= int64(startPiece.chunkSize())
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
endPiece := f.t.piece(endPieceIndex)
|
||||||
|
startChunk := int((f.offset+f.length)%f.t.info.PieceLength) * int(endPiece.numChunks()) / int(endPiece.length())
|
||||||
|
lastChunkIndex := int(endPiece.lastChunkIndex())
|
||||||
|
bitmap.Flip(endPiece.dirtyChunks, startChunk, int(endPiece.numChunks())).IterTyped(func(chunk int) bool {
|
||||||
|
if chunk == lastChunkIndex {
|
||||||
|
left -= int64(endPiece.chunkIndexSpec(pp.Integer(chunk)).Length)
|
||||||
|
} else {
|
||||||
|
left -= int64(endPiece.chunkSize())
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// The relative file path for a multi-file torrent, and the torrent name for a
|
// The relative file path for a multi-file torrent, and the torrent name for a
|
||||||
// single-file torrent.
|
// single-file torrent.
|
||||||
func (f *File) DisplayPath() string {
|
func (f *File) DisplayPath() string {
|
||||||
|
|
Loading…
Reference in New Issue