Example #1
0
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
        {
            if (request.Aborted)
            {
                throw new WebException("The request was canceled.", null, WebExceptionStatus.RequestCanceled);
            }

            if (disposed)
            {
                throw new WebException("stream is closed", WebExceptionStatus.ConnectionClosed);
            }

            if (isRead)
            {
                throw new NotSupportedException("this stream does not allow writing");
            }

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

            if (sendChunked)
            {
                lock (locker)
                {
                    pendingWrites++;
                    pending.Reset();
                }
            }

            WebAsyncResult result   = new WebAsyncResult(cb, state);
            AsyncCallback  callback = new AsyncCallback(WriteAsyncCB);

            if (sendChunked)
            {
                requestWritten = true;

                string cSize     = String.Format("{0:X}\r\n", size);
                byte[] head      = Encoding.ASCII.GetBytes(cSize);
                int    chunkSize = 2 + size + head.Length;
                byte[] newBuffer = new byte[chunkSize];
                Buffer.BlockCopy(head, 0, newBuffer, 0, head.Length);
                Buffer.BlockCopy(buffer, offset, newBuffer, head.Length, size);
                Buffer.BlockCopy(crlf, 0, newBuffer, head.Length + size, crlf.Length);

                if (allowBuffering)
                {
                    if (writeBuffer == null)
                    {
                        writeBuffer = new MemoryStream();
                    }
                    writeBuffer.Write(buffer, offset, size);
                    totalWritten += size;
                }

                buffer = newBuffer;
                offset = 0;
                size   = chunkSize;
            }
            else
            {
                CheckWriteOverflow(request.ContentLength, totalWritten, size);

                if (allowBuffering)
                {
                    if (writeBuffer == null)
                    {
                        writeBuffer = new MemoryStream();
                    }
                    writeBuffer.Write(buffer, offset, size);
                    totalWritten += size;

                    if (request.ContentLength <= 0 || totalWritten < request.ContentLength)
                    {
                        result.SetCompleted(true, 0);
                        result.DoCallback();
                        return(result);
                    }

                    result.AsyncWriteAll = true;
                    requestWritten       = true;
                    buffer = writeBuffer.GetBuffer();
                    offset = 0;
                    size   = (int)totalWritten;
                }
            }

            try
            {
                result.InnerAsyncResult = cnc.BeginWrite(request, buffer, offset, size, callback, result);
                if (result.InnerAsyncResult == null)
                {
                    if (!result.IsCompleted)
                    {
                        result.SetCompleted(true, 0);
                    }
                    result.DoCallback();
                }
            }
            catch (Exception)
            {
                if (!IgnoreIOErrors)
                {
                    throw;
                }
                result.SetCompleted(true, 0);
                result.DoCallback();
            }
            totalWritten += size;
            return(result);
        }