public async ReusableTask <int> ReadAsync(ITorrentFileInfo file, long offset, byte[] buffer, int bufferOffset, int count) { Check.File(file); Check.Buffer(buffer); if (offset < 0 || offset + count > file.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); } using (await Limiter.EnterAsync()) { using var rented = await StreamCache.GetOrCreateStreamAsync(file, FileAccess.Read).ConfigureAwait(false); await MainLoop.SwitchToThreadpool(); if (rented.Stream.Length < offset + count) { return(0); } if (rented.Stream.Position != offset) { await rented.Stream.SeekAsync(offset); } ReadMonitor?.AddDelta(count); return(await rented.Stream.ReadAsync(buffer, bufferOffset, count)); } }
bool Read(ITorrentData manager, long offset, byte [] buffer, int count) { ReadMonitor.AddDelta(count); if (offset < 0 || offset + count > manager.Size) { throw new ArgumentOutOfRangeException(nameof(offset)); } int i; int totalRead = 0; var files = manager.Files; for (i = 0; i < files.Length; i++) { if (offset < files[i].Length) { break; } offset -= files[i].Length; } while (totalRead < count) { int fileToRead = (int)Math.Min(files[i].Length - offset, count - totalRead); fileToRead = Math.Min(fileToRead, Piece.BlockSize); if (fileToRead != Writer.Read(files[i], offset, buffer, totalRead, fileToRead)) { return(false); } offset += fileToRead; totalRead += fileToRead; if (offset >= files[i].Length) { offset = 0; i++; } } return(true); }
ReusableTask <int> ReadFromFilesAsync(ITorrentData torrent, BlockInfo block, byte[] buffer) { ReadMonitor.AddDelta(block.RequestLength); return(Writer.ReadFromFilesAsync(torrent, block, buffer)); }