Skip to content

Commit

Permalink
[core] Move some more code to the helper methods
Browse files Browse the repository at this point in the history
  • Loading branch information
alanmcgovern committed Feb 18, 2021
1 parent 42f4b8a commit 59d0208
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 26 deletions.
32 changes: 21 additions & 11 deletions src/MonoTorrent.Tests/Client/TorrentDataExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,7 @@
//


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

using MonoTorrent.BEncoding;
using MonoTorrent.Client.Connections;
using MonoTorrent.Client.Messages;
using MonoTorrent.Client.Messages.Standard;

using NUnit.Framework;

Expand All @@ -61,6 +50,23 @@ public void BlocksPerPiece ()
Assert.AreEqual (2, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.BlocksPerPiece (1));
Assert.AreEqual (1, new Data { Size = Piece.BlockSize * 4 + 1, PieceLength = Piece.BlockSize * 2 }.BlocksPerPiece (2));
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));
}

[Test]
public void ByteOffsetToPieceIndex ()
{
Assert.AreEqual (0, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.ByteOffsetToPieceIndex (0));
Assert.AreEqual (0, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.ByteOffsetToPieceIndex (1));
Assert.AreEqual (0, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.ByteOffsetToPieceIndex (Piece.BlockSize * 2 - 1));
Assert.AreEqual (1, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.ByteOffsetToPieceIndex (Piece.BlockSize * 2));
Assert.AreEqual (1, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.ByteOffsetToPieceIndex (Piece.BlockSize * 2 + 1));
Assert.AreEqual (1, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.ByteOffsetToPieceIndex (Piece.BlockSize * 3 - 1));
Assert.AreEqual (1, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.ByteOffsetToPieceIndex (Piece.BlockSize * 3));
Assert.AreEqual (2, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.ByteOffsetToPieceIndex (Piece.BlockSize * 4));

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

[Test]
Expand All @@ -71,6 +77,8 @@ public void BytesPerPiece ()

Assert.AreEqual (1, new Data { Size = Piece.BlockSize * 4 + 1, PieceLength = Piece.BlockSize * 2 }.BytesPerPiece (2));
Assert.AreEqual (Piece.BlockSize - 1, new Data { Size = Piece.BlockSize * 5 - 1, PieceLength = Piece.BlockSize * 2 }.BytesPerPiece (2));

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

[Test]
Expand All @@ -80,6 +88,8 @@ public void PieceCount ()
Assert.AreEqual (2, new Data { Size = Piece.BlockSize * 4 - 1, PieceLength = Piece.BlockSize * 2 }.PieceCount ());
Assert.AreEqual (2, new Data { Size = Piece.BlockSize * 4, PieceLength = Piece.BlockSize * 2 }.PieceCount ());
Assert.AreEqual (3, new Data { Size = Piece.BlockSize * 4 + 1, PieceLength = Piece.BlockSize * 2 }.PieceCount ());

Assert.AreEqual (262144, new Data { Size = (long) (int.MaxValue) * 4, PieceLength = Piece.BlockSize * 2 }.PieceCount ());
}
}
}
18 changes: 16 additions & 2 deletions src/MonoTorrent.Tests/Streaming/StreamProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,10 @@ public async Task ReadLastByte ()
provider.Manager.Bitfield.SetAll (true); // the public API shouldn't allow this.

using var stream = await provider.CreateStreamAsync (provider.Files[0], prebuffer: false, CancellationToken.None).WithTimeout ();
stream.Seek (1, SeekOrigin.End);
stream.Seek (-1, SeekOrigin.End);
Assert.AreEqual (1, await stream.ReadAsync (new byte[1], 0, 1).WithTimeout ());

stream.Seek (1, SeekOrigin.End);
stream.Seek (-1, SeekOrigin.End);
Assert.AreEqual (1, await stream.ReadAsync (new byte[5], 0, 5).WithTimeout ());
}

Expand All @@ -178,6 +178,20 @@ public async Task SeekBeforeStart ()
Assert.AreEqual (0, stream.Position);
}

[Test]
public async Task SeekToMiddle ()
{
var provider = new StreamProvider (Engine, "testDir", Torrent);

await provider.StartAsync ();
await provider.Manager.WaitForState (TorrentState.Downloading);
provider.Manager.Bitfield.SetAll (true); // should not be allowed by public API.

using var stream = await provider.CreateStreamAsync (provider.Files[0], prebuffer: false, CancellationToken.None);
stream.Seek (12345, SeekOrigin.Begin);
Assert.AreEqual (provider.Manager.ByteOffsetToPieceIndex (12345), provider.Requester.HighPriorityPieceIndex);
}

[Test]
public async Task SeekPastEnd ()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,7 @@ internal void SeekToPosition (ITorrentFileInfo file, long position)
/// <param name="position"></param>
internal void ReadToPosition (ITorrentFileInfo file, long position)
{
var pieceIndex = TorrentData.ByteOffsetToPieceIndex (position + file.OffsetInTorrent);
HighPriorityPieceIndex = Math.Min (file.EndPieceIndex, pieceIndex);
HighPriorityPieceIndex = Math.Min (file.EndPieceIndex, TorrentData.ByteOffsetToPieceIndex (position + file.OffsetInTorrent));
}
}
}
9 changes: 3 additions & 6 deletions src/MonoTorrent/MonoTorrent.Streaming/LocalStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,8 @@ public override async Task<int> ReadAsync (byte[] buffer, int offset, int count,
return 0;

// Take our current position into account when calculating the start/end pieces of the data we're reading.
var startPiece = (int) ((torrentFileStartOffset + Position) / Manager.Torrent.PieceLength);
var endPiece = (int) ((torrentFileStartOffset + Position + count) / Manager.Torrent.PieceLength);
if (Length % Manager.Torrent.PieceLength == 0 && endPiece == Manager.Torrent.Pieces.Count)
endPiece--;

var startPiece = Manager.ByteOffsetToPieceIndex (torrentFileStartOffset + Position);
var endPiece = Math.Min (File.EndPieceIndex, Manager.ByteOffsetToPieceIndex (torrentFileStartOffset + Position + count));
while (Manager.State != TorrentState.Stopped && Manager.State != TorrentState.Error) {
bool allAvailable = true;
for (int i = startPiece; i <= endPiece && allAvailable; i++)
Expand Down Expand Up @@ -148,7 +145,7 @@ public override long Seek (long offset, SeekOrigin origin)
newPosition = position + offset;
break;
case SeekOrigin.End:
newPosition = Length - offset;
newPosition = Length + offset;
break;
default:
throw new NotSupportedException ();
Expand Down
2 changes: 1 addition & 1 deletion src/MonoTorrent/MonoTorrent.Streaming/StreamProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class StreamProvider
{
LocalStream ActiveStream { get; set; }
ClientEngine Engine { get; }
StreamingPieceRequester Requester { get; }
internal StreamingPieceRequester Requester { get; }

/// <summary>
/// Returns true when the <see cref="StreamProvider"/> has been started.
Expand Down
8 changes: 4 additions & 4 deletions src/MonoTorrent/MonoTorrent/ITorrentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,19 @@ public static int BlocksPerPiece (this ITorrentData self, int pieceIndex)
if (pieceIndex < self.PieceCount () - 1)
return self.PieceLength / Piece.BlockSize;

var remainder = (int) self.Size - self.PieceLength * pieceIndex;
return (remainder + Piece.BlockSize - 1) / Piece.BlockSize;
var remainder = self.Size - self.PieceIndexToByteOffset (pieceIndex);
return (int) ((remainder + Piece.BlockSize - 1) / Piece.BlockSize);
}

public static int BytesPerPiece (this ITorrentData self, int pieceIndex)
{
if (pieceIndex < self.PieceCount () - 1)
return self.PieceLength;
return (int) (self.Size - (long) self.PieceLength * pieceIndex);
return (int) (self.Size - self.PieceIndexToByteOffset (pieceIndex));
}

public static int ByteOffsetToPieceIndex (this ITorrentData self, long offset)
=> (int) ((offset / self.PieceLength) + (offset % self.PieceLength != 0 ? 1 : 0));
=> (int) (offset / self.PieceLength);

/// <summary>
/// The number of pieces in the torrent
Expand Down

0 comments on commit 59d0208

Please sign in to comment.