Skip to content

Commit

Permalink
[core] Support unusual piece sizes (again?)
Browse files Browse the repository at this point in the history
I unintentionally removed support for piece sizes which
were not multiples of 16kB. It  came as a surprise to
learn these were not officially forbidden by the spec,
the spec just calls for 'usually a multiple of 2'.

Strange.
  • Loading branch information
alanmcgovern committed Feb 20, 2021
1 parent d532927 commit f438ddd
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/MonoTorrent.Tests/Client/StandardPickerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,18 @@ public void CreateNormalPiece ()
Assert.AreEqual (Piece.BlockSize * 1, piece.Blocks[2].RequestLength);
}

[Test]
public void CreatePiece_NotMultipleOf16KB ()
{
var totalSize = 2318336;
var piece = new Piece (0, totalSize);
Assert.AreEqual (142, piece.BlockCount);

for (int i = 0; i < piece.BlockCount - 1; i++)
Assert.AreEqual (Piece.BlockSize, piece[i].RequestLength);
Assert.AreEqual (totalSize - (Piece.BlockSize * 141), piece[141].RequestLength);
}

[Test]
public void PickBundle ()
{
Expand Down
2 changes: 2 additions & 0 deletions src/MonoTorrent.Tests/Client/TorrentDataExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public void BlocksPerPiece ()
Assert.AreEqual (1, new Data { Size = Piece.BlockSize * 5 - 1, PieceLength = Piece.BlockSize * 2 }.BlocksPerPiece (2));

Assert.AreEqual (2, new Data { Size = (long) (int.MaxValue) * 4, PieceLength = Piece.BlockSize * 2 }.BlocksPerPiece (0));

Assert.AreEqual (142, new Data { Size = 16 * 1024 * 1024, PieceLength = 2318336 }.BlocksPerPiece (0));
}

[Test]
Expand Down
2 changes: 1 addition & 1 deletion src/MonoTorrent/MonoTorrent/ITorrentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static class ITorrentDataExtensions
public static int BlocksPerPiece (this ITorrentData self, int pieceIndex)
{
if (pieceIndex < self.PieceCount () - 1)
return self.PieceLength / Piece.BlockSize;
return (Piece.BlockSize - 1 + self.PieceLength) / Piece.BlockSize;

var remainder = self.Size - self.PieceIndexToByteOffset (pieceIndex);
return (int) ((remainder + Piece.BlockSize - 1) / Piece.BlockSize);
Expand Down

0 comments on commit f438ddd

Please sign in to comment.