Exemple #1
0
        /// <summary>
        /// Reads the data async.
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="buffer">The buffer to read into.</param>
        /// <param name="offset">The offset into the buffer where data is written.</param>
        /// <param name="count">The number of bytes to read.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken)
        {
            Task <int> rtask;
            Task       rt;

            if (m_passthrough)
            {
                rtask = m_parent.ReadAsync(buffer, offset, count, cancellationToken);
                rt    = await Task.WhenAny(Task.Delay(m_idletime), m_timeouttask, m_stoptask, rtask);

                if (rt != rtask)
                {
                    m_cs.Cancel();
                    if (rt == m_stoptask)
                    {
                        throw new TaskCanceledException();
                    }
                    else
                    {
                        throw new HttpException(HttpStatusCode.RequestTimeout);
                    }
                }

                return(await rtask);
            }

            if (m_bytesleft <= 0)
            {
                return(0);
            }

            rtask = m_parent.ReadAsync(buffer, offset, (int)Math.Min(count, m_bytesleft), m_cs.Token);
            rt    = await Task.WhenAny(Task.Delay(m_idletime), m_timeouttask, m_stoptask, rtask);

            if (rt != rtask)
            {
                m_cs.Cancel();
                if (rt == m_stoptask)
                {
                    throw new TaskCanceledException();
                }
                else
                {
                    throw new HttpException(HttpStatusCode.RequestTimeout);
                }
            }

            var r = await rtask;

            if (r == 0)
            {
                return(r);
            }

            m_bytesleft -= r;
            m_bytesread += r;
            return(r);
        }
Exemple #2
0
        /// <summary>
        /// Reads the data async.
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="buffer">The buffer to read into.</param>
        /// <param name="offset">The offset into the buffer where data is written.</param>
        /// <param name="count">The number of bytes to read.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken)
        {
            if (m_completed)
            {
                return(0);
            }

            if (count > m_buf.Length)
            {
                Array.Resize(ref m_buf, count + 1024);
            }

            var rtask = m_parent.ReadAsync(m_buf, m_buffersize, Math.Min(count, m_buf.Length - m_buffersize), m_cs.Token);
            var rt    = await Task.WhenAny(Task.Delay(m_idletime), m_timeouttask, m_stoptask, rtask);

            if (rt != rtask)
            {
                m_cs.Cancel();
                if (rt == m_stoptask)
                {
                    throw new TaskCanceledException();
                }
                else
                {
                    throw new HttpException(HttpStatusCode.RequestTimeout);
                }
            }

            var r = await rtask;

            m_buffersize += r;
            if (r == 0)
            {
                return(r);
            }

            var ix  = FindDelimiterMatch();
            var res = Math.Max(0, ix);

            if (res != 0)
            {
                Array.Copy(m_buf, 0, buffer, offset, res);
            }

            if (m_buffersize - ix >= m_delimiter.Length)
            {
                m_completed = true;
                m_parent.AddToBuffer(m_buf, ix + m_delimiter.Length, m_buffersize - ix - m_delimiter.Length);
            }
            else
            {
                Array.Copy(m_buf, ix, m_buf, 0, m_buffersize - ix);
                m_buffersize -= ix;
            }

            m_read += res;
            return(res);
        }
        /// <summary>
        /// Reads the data async.
        /// </summary>
        /// <returns>The awaitable task.</returns>
        /// <param name="buffer">The buffer to read into.</param>
        /// <param name="offset">The offset into the buffer where data is written.</param>
        /// <param name="count">The number of bytes to read.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken)
        {
            if (m_completed)
            {
                return(0);
            }

            if (count > m_buf.Length)
            {
                Array.Resize(ref m_buf, count + 1024);
            }

            Task <int> rtask;
            Task       rt;

            using (var cs = new CancellationTokenSource(m_idletime))
                using (cancellationToken.Register(() => cs.Cancel()))
                {
                    rtask = m_parent.ReadAsync(m_buf, m_buffersize, Math.Max(m_delimiter.Length - m_buffersize, Math.Min(count, m_buf.Length - m_buffersize)), cs.Token);
                    rt    = await Task.WhenAny(m_timeouttask, m_stoptask, rtask);
                }

            if (rt != rtask)
            {
                if (rt == m_stoptask)
                {
                    throw new TaskCanceledException();
                }
                else
                {
                    throw new HttpException(HttpStatusCode.RequestTimeout);
                }
            }

            var r = rtask.Result;

            m_buffersize += r;
            if (r == 0)
            {
                return(r);
            }

            // Return as much as possible
            var bytes = Math.Min(count, m_buffersize);

            // Check for the delimiter
            var ix = FindDelimiterMatch();

            // If we found a (partial) delimiter match,
            // only return bytes leading up to the marker
            if (ix >= 0)
            {
                bytes = Math.Min(count, ix);
            }

            // Copy bytes to the reader
            if (bytes != 0)
            {
                Array.Copy(m_buf, 0, buffer, offset, bytes);
            }

            // Store what we read ahead in the buffer
            if (bytes != m_buffersize)
            {
                Array.Copy(m_buf, ix, m_buf, 0, m_buffersize - ix);
            }

            // Adjust with the bytes taken
            m_buffersize -= bytes;

            // If we found the delimiter in full, we are done
            if (ix > 0 && m_buffersize >= m_delimiter.Length)
            {
                m_completed = true;
                // Drop the delimiter from the buffer
                m_buffersize -= m_delimiter.Length;
                // If we have more, stuff it back into the parent's buffer
                if (m_buffersize != 0)
                {
                    m_parent.UnreadBytesIntoBuffer(m_buf, m_delimiter.Length, m_buffersize);
                }
                m_buffersize = 0;
            }

            m_read += bytes;
            return(bytes);
        }