public override IAsyncResult BeginRead(byte [] buffer, int offset, int size,
AsyncCallback cb, object state)
{
if (!isRead)
{
throw new NotSupportedException("this stream does not allow reading");
}
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
int length = buffer.Length;
if (offset < 0 || length < offset)
{
throw new ArgumentOutOfRangeException("offset");
}
if (size < 0 || (length - offset) < size)
{
throw new ArgumentOutOfRangeException("size");
}
lock (locker) {
pendingReads++;
pending.Reset();
}
WebAsyncResult result = new WebAsyncResult(cb, state, buffer, offset, size);
if (totalRead >= contentLength)
{
result.SetCompleted(true, -1);
result.DoCallback();
return(result);
}
int remaining = readBufferSize - readBufferOffset;
if (remaining > 0)
{
int copy = (remaining > size) ? size : remaining;
Buffer.BlockCopy(readBuffer, readBufferOffset, buffer, offset, copy);
readBufferOffset += copy;
offset += copy;
size -= copy;
totalRead += copy;
if (size == 0 || totalRead >= contentLength)
{
result.SetCompleted(true, copy);
result.DoCallback();
return(result);
}
result.NBytes = copy;
}
if (cb != null)
{
cb = cb_wrapper;
}
if (contentLength != Int32.MaxValue && contentLength - totalRead < size)
{
size = contentLength - totalRead;
}
if (!read_eof)
{
result.InnerAsyncResult = cnc.BeginRead(request, buffer, offset, size, cb, result);
}
else
{
result.SetCompleted(true, result.NBytes);
result.DoCallback();
}
return(result);
}