From f438dddfa4341685c294c2ac41e4e02f15834c1e Mon Sep 17 00:00:00 2001 From: Alan McGovern Date: Fri, 19 Feb 2021 19:59:25 +0000 Subject: [PATCH] [core] Support unusual piece sizes (again?) 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. --- src/MonoTorrent.Tests/Client/StandardPickerTests.cs | 12 ++++++++++++ .../Client/TorrentDataExtensionsTests.cs | 2 ++ src/MonoTorrent/MonoTorrent/ITorrentData.cs | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/MonoTorrent.Tests/Client/StandardPickerTests.cs b/src/MonoTorrent.Tests/Client/StandardPickerTests.cs index 3fff64a48..e04d43c05 100644 --- a/src/MonoTorrent.Tests/Client/StandardPickerTests.cs +++ b/src/MonoTorrent.Tests/Client/StandardPickerTests.cs @@ -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 () { diff --git a/src/MonoTorrent.Tests/Client/TorrentDataExtensionsTests.cs b/src/MonoTorrent.Tests/Client/TorrentDataExtensionsTests.cs index 00c77938c..637c21329 100644 --- a/src/MonoTorrent.Tests/Client/TorrentDataExtensionsTests.cs +++ b/src/MonoTorrent.Tests/Client/TorrentDataExtensionsTests.cs @@ -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] diff --git a/src/MonoTorrent/MonoTorrent/ITorrentData.cs b/src/MonoTorrent/MonoTorrent/ITorrentData.cs index 53cf0675e..1674f04f5 100644 --- a/src/MonoTorrent/MonoTorrent/ITorrentData.cs +++ b/src/MonoTorrent/MonoTorrent/ITorrentData.cs @@ -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);