示例#1
0
        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));
            }
        }
示例#2
0
        ReusableTask Tick(int delta, bool waitForBufferedIO)
        {
            UpdateTimer.Restart();

            ReadMonitor.Tick(delta);
            WriteMonitor.Tick(delta);

            WriteLimiter.UpdateChunks(Settings.MaximumDiskWriteRate, WriteRate);
            ReadLimiter.UpdateChunks(Settings.MaximumDiskReadRate, ReadRate);

            var processTask = ProcessBufferedIOAsync();

            return(waitForBufferedIO ? processTask : ReusableTask.CompletedTask);
        }
示例#3
0
        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);
        }
示例#4
0
 ReusableTask <int> ReadFromFilesAsync(ITorrentData torrent, BlockInfo block, byte[] buffer)
 {
     ReadMonitor.AddDelta(block.RequestLength);
     return(Writer.ReadFromFilesAsync(torrent, block, buffer));
 }