public void PushChunk(byte[] buffer, int length)
        {
            if (buffer == null)
            {
                _queueChunks.Enqueue(null);
                _queueWaiter.Set();
                return;
            }

            if (!chunkStore.TryDequeue(out StreamChunk chunk))
            {
                chunk = new StreamChunk(new byte[buffer.Length]);
            }

            Array.Copy(buffer, 0, chunk.Buffer, 0, length);
            chunk.Length = length;

            _queueChunks.Enqueue(chunk);
            _queueWaiter.Set();
        }
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (_finished)
            {
                return(0);
            }

            if (_chunk == null || _position == _chunk.Length)
            {
                _chunk = PopChunk(CancellationToken.None);
                if (_chunk == null || _chunk.Length == 0)
                {
                    _finished = true;
                    return(0);
                }
                _position = 0;
            }

            var bufferAvailable = _chunk.Length - _position;

            if (bufferAvailable >= count)
            {
                Array.Copy(_chunk.Buffer, _position, buffer, offset, count);
                _position += count;
            }
            else
            {
                count = bufferAvailable;

                Array.Copy(_chunk.Buffer, _position, buffer, offset, count);
                _position = 0;

                chunkStore.Enqueue(_chunk);
                _chunk = null;
            }

            return(count);
        }
예제 #3
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (IsFinised)
            {
                return(0);
            }

            if (_chunk == null || _position == _chunk.Length)
            {
                if (IsDirect && _queueChunks.IsEmpty)
                {
                    try
                    {
                        return(WriteBackStream.Read(buffer, offset, count));
                    }
                    catch
                    {
                        return(0);
                    }
                }

                _chunk = PopChunk(CancellationToken.None);
                if (_chunk == null || _chunk.Length == 0)
                {
                    if (IsDirect)
                    {
                        try
                        {
                            return(WriteBackStream.Read(buffer, offset, count));
                        }
                        catch
                        {
                            return(0);
                        }
                    }

                    IsFinised = true;
                    return(0);
                }
                _position = 0;
            }

            var bufferAvailable = _chunk.Length - _position;

            if (bufferAvailable >= count)
            {
                Array.Copy(_chunk.Buffer, _position, buffer, offset, count);
                _position += count;
            }
            else
            {
                count = bufferAvailable;

                Array.Copy(_chunk.Buffer, _position, buffer, offset, count);
                _position = 0;

                chunkStore.Enqueue(_chunk);
                _chunk = null;
            }

            return(count);
        }