public override int EndRead(IAsyncResult r) { WebAsyncResult result = (WebAsyncResult)r; if (result.EndCalled) { int xx = result.NBytes; return((xx >= 0) ? xx : 0); } result.EndCalled = true; if (!result.IsCompleted) { int nbytes = -1; try { nbytes = cnc.EndRead(request, result); } catch (Exception exc) { lock (locker) { pendingReads--; if (pendingReads == 0) { pending.Set(); } } nextReadCalled = true; cnc.Close(true); result.SetCompleted(false, exc); result.DoCallback(); throw; } if (nbytes < 0) { nbytes = 0; read_eof = true; } totalRead += nbytes; result.SetCompleted(false, nbytes + result.NBytes); result.DoCallback(); if (nbytes == 0) { contentLength = totalRead; } } lock (locker) { pendingReads--; if (pendingReads == 0) { pending.Set(); } } if (totalRead >= contentLength && !nextReadCalled) { ReadAll(); } int nb = result.NBytes; return((nb >= 0) ? nb : 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); }
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); }