Example #1
0
        /// <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));
        }