diff options
author | Feross Aboukhadijeh <feross@feross.org> | 2021-03-02 00:11:03 +0300 |
---|---|---|
committer | Feross Aboukhadijeh <feross@feross.org> | 2021-03-02 00:11:03 +0300 |
commit | e513375aacf9dfbca24e135bc55ac59570dbc07e (patch) | |
tree | a43a3c31367bb63a8d9bd9294c3fc4f996dba9ae /lib | |
parent | 4cbdf1c296d86416ad587fc74571cebb1d4735ff (diff) |
Fix file progress sometimes < 0 and > 1
Code reviewed by @jhiesey
Diffstat (limited to 'lib')
-rw-r--r-- | lib/file.js | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/lib/file.js b/lib/file.js index abd4f5d..caa395d 100644 --- a/lib/file.js +++ b/lib/file.js @@ -38,30 +38,43 @@ class File extends EventEmitter { get downloaded () { if (!this._torrent.bitfield) return 0 - const { pieces, bitfield, pieceLength } = this._torrent + const { pieces, bitfield, pieceLength, lastPieceLength } = this._torrent const { _startPiece: start, _endPiece: end } = this - const piece = pieces[start] - // First piece may have an offset, e.g. irrelevant bytes from the end of - // the previous file - const irrelevantFirstPieceBytes = this.offset % pieceLength - let downloaded = bitfield.get(start) - ? pieceLength - irrelevantFirstPieceBytes - : Math.max(pieceLength - irrelevantFirstPieceBytes - piece.missing, 0) + const getPieceLength = (pieceIndex) => ( + pieceIndex === pieces.length - 1 ? lastPieceLength : pieceLength + ) - for (let index = start + 1; index <= end; ++index) { - if (bitfield.get(index)) { + const getPieceDownloaded = (pieceIndex) => { + const len = pieceIndex === pieces.length - 1 ? lastPieceLength : pieceLength + if (bitfield.get(pieceIndex)) { // verified data - downloaded += pieceLength + return len } else { // "in progress" data - const piece = pieces[index] - downloaded += pieceLength - piece.missing + return len - pieces[pieceIndex].missing } } - const irrelevantLastPieceBytes = pieceLength - ((this.offset + this.length) % pieceLength) - downloaded -= irrelevantLastPieceBytes + let downloaded = 0 + for (let index = start; index <= end; index += 1) { + const pieceDownloaded = getPieceDownloaded(index) + downloaded += pieceDownloaded + + if (index === start) { + // First piece may have an offset, e.g. irrelevant bytes from the end of + // the previous file + const irrelevantFirstPieceBytes = this.offset % pieceLength + downloaded -= Math.min(irrelevantFirstPieceBytes, pieceDownloaded) + } + + if (index === end) { + // Last piece may have an offset, e.g. irrelevant bytes from the start + // of the next file + const irrelevantLastPieceBytes = getPieceLength(end) - (this.offset + this.length) % pieceLength + downloaded -= Math.min(irrelevantLastPieceBytes, pieceDownloaded) + } + } return downloaded } |