//
// Combined sync/async read method. For sync request asyncRequest==null.
//
private int ProcessRead(byte[] buffer, int offset, int count, BufferAsyncResult asyncResult)
{
ValidateParameters(buffer, offset, count);
if (Interlocked.Exchange(ref _nestedRead, 1) == 1)
{
throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, (asyncResult != null? "BeginRead":"Read"), "read"));
}
// If this is an async operation, get the AsyncProtocolRequest to use.
// We do this only after we verify we're the sole write operation in flight.
AsyncProtocolRequest asyncRequest = GetOrCreateProtocolRequest(ref _readProtocolRequest, asyncResult);
bool failed = false;
try
{
int copyBytes;
if (InternalBufferCount != 0)
{
copyBytes = InternalBufferCount > count ? count : InternalBufferCount;
if (copyBytes != 0)
{
Buffer.BlockCopy(InternalBuffer, InternalOffset, buffer, offset, copyBytes);
SkipBytes(copyBytes);
}
asyncRequest?.CompleteUser(copyBytes);
return(copyBytes);
}
return(StartReading(buffer, offset, count, asyncRequest));
}
catch (Exception e)
{
_sslState.FinishRead(null);
failed = true;
if (e is IOException)
{
throw;
}
throw new IOException(SR.net_io_read, e);
}
finally
{
if (asyncRequest == null || failed)
{
_nestedRead = 0;
}
}
}