Ejemplo n.º 1
0
        public async override Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            // TODO: Validate buffer
            if (_disposed)
            {
                return(0);
            }

            try
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (_expectChunkHeader)
                {
                    System.Diagnostics.Debug.Assert(_chunkBytesRemaining == 0);
                    string headerLine = await _inner.ReadLineAsync(cancellationToken);

                    if (!long.TryParse(headerLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out _chunkBytesRemaining))
                    {
                        throw new IOException("Invalid chunk header: " + headerLine);
                    }
                    _expectChunkHeader = false;
                }

                int read = 0;
                if (_chunkBytesRemaining > 0)
                {
                    // Not the last (empty) chunk.
                    int toRead = (int)Math.Min(count, _chunkBytesRemaining);
                    read = await _inner.ReadAsync(buffer, offset, toRead, cancellationToken);

                    _chunkBytesRemaining -= read;
                    System.Diagnostics.Debug.Assert(_chunkBytesRemaining >= 0, "Negative bytes remaining? " + _chunkBytesRemaining);
                }
                // TODO: else, drain trailer headers.

                if (_chunkBytesRemaining == 0)
                {
                    // End of chunk, read the terminator CRLF
                    string trailerLine = await _inner.ReadLineAsync(cancellationToken);

                    System.Diagnostics.Debug.Assert(string.IsNullOrEmpty(trailerLine));
                    _expectChunkHeader = true;
                }

                if (read == 0)
                {
                    Dispose();
                }
                return(read);
            }
            catch (Exception)
            {
                Dispose();
                throw;
            }
        }
Ejemplo n.º 2
0
        public async override Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            // TODO: Validate buffer
            ThrowIfDisposed();

            if (_done)
            {
                return(0);
            }

            cancellationToken.ThrowIfCancellationRequested();

            if (_chunkBytesRemaining == 0)
            {
                string headerLine = await _inner.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                if (!long.TryParse(headerLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out _chunkBytesRemaining))
                {
                    throw new IOException("Invalid chunk header: " + headerLine);
                }
            }

            int read = 0;

            if (_chunkBytesRemaining > 0)
            {
                int toRead = (int)Math.Min(count, _chunkBytesRemaining);
                read = await _inner.ReadAsync(buffer, offset, toRead, cancellationToken).ConfigureAwait(false);

                if (read == 0)
                {
                    throw new EndOfStreamException();
                }

                _chunkBytesRemaining -= read;
            }

            if (_chunkBytesRemaining == 0)
            {
                // End of chunk, read the terminator CRLF
                var trailer = await _inner.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                if (trailer.Length > 0)
                {
                    throw new IOException("Invalid chunk trailer");
                }

                if (read == 0)
                {
                    _done = true;
                }
            }

            return(read);
        }