/// <summary> /// Asynchronously reads bytes from the stream into the provided buffer. /// </summary> /// <param name="buffer">The buffer to read bytes into.</param> /// <param name="offset">The offset in the buffer which is where bytes will be written to.</param> /// <param name="count">The maximum number of bytes to read.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>The number of bytes read into the buffer.</returns> public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { var actualCount = count; if (Position + count > Length) { actualCount = (int)(Length - Position); } if (actualCount <= 0) { return(0); } return(await _rangeReader.ReadAsync(_position, buffer, offset, actualCount)); }
private async Task <int> GetBufferOffsetAsync(int count) { if (Position >= Length) { return(-1); } if (Position < BufferPosition) { // Determine the read offset by setting a desired buffer size. var desiredBufferSize = Math.Max(count, _bufferSizeProvider.GetNextBufferSize()); if (desiredBufferSize > Length) { desiredBufferSize = (int)Length; } var available = Length - Position; long readOffset; if (available < desiredBufferSize) { readOffset = Math.Max(0, Length - desiredBufferSize); } else { readOffset = Position; } // Read up until the old position (or up to the end, if this is the first read). var readCount = (int)(BufferPosition - readOffset); var newBuffer = new byte[readCount]; var actualRead = await _rangeReader.ReadAsync(readOffset, newBuffer, 0, readCount); _buffer.Prepend(newBuffer); BufferPosition = readOffset; } return((int)(Position - BufferPosition)); }