private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { // We loop to this method from the callback. // If the last chunk was just completed from async callback (count < 0), we complete user request. if (count >= 0) { byte[] outBuffer = null; do { int chunkBytes = Math.Min(count, NegoState.MaxWriteDataSize); int encryptedBytes; try { encryptedBytes = _negoState.EncryptData(buffer, offset, chunkBytes, ref outBuffer); } catch (Exception e) { throw new IOException(SR.net_io_encrypt, e); } if (asyncRequest != null) { // prepare for the next request asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, null); IAsyncResult ar = InnerStreamAPM.BeginWrite(outBuffer, 0, encryptedBytes, s_writeCallback, asyncRequest); if (!ar.CompletedSynchronously) { return; } InnerStreamAPM.EndWrite(ar); } else { InnerStream.Write(outBuffer, 0, encryptedBytes); } offset += chunkBytes; count -= chunkBytes; } while (count != 0); } if (asyncRequest != null) { asyncRequest.CompleteUser(); } }
private void EndWrite(IAsyncResult asyncResult) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) { #endif _negoState.CheckThrow(true); if (!_negoState.CanGetSecureStream) { InnerStreamAPM.EndWrite(asyncResult); return; } if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } BufferAsyncResult bufferResult = asyncResult as BufferAsyncResult; if (bufferResult == null) { throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), "asyncResult"); } if (Interlocked.Exchange(ref _NestedWrite, 0) == 0) { throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite")); } // No "artificial" timeouts implemented so far, InnerStream controls timeout. bufferResult.InternalWaitForCompletion(); if (bufferResult.Result is Exception) { if (bufferResult.Result is IOException) { throw (Exception)bufferResult.Result; } throw new IOException(SR.net_io_write, (Exception)bufferResult.Result); } #if DEBUG } #endif }