/// <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); }
/// <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); }