コード例 #1
0
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
        {
            if (disposed)
            {
                throw new WebException("stream is closed", WebExceptionStatus.ConnectionClosed);
            }

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