private static Stream AsStreamInternal(Object windowsRuntimeStream, Int32 bufferSize, String invokedMethodName, bool forceBufferSize)
{
if (windowsRuntimeStream == null)
{
throw new ArgumentNullException(nameof(windowsRuntimeStream));
}
if (bufferSize < 0)
{
throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_WinRtAdapterBufferSizeMayNotBeNegative);
}
Debug.Assert(!String.IsNullOrWhiteSpace(invokedMethodName));
Contract.Ensures(Contract.Result <Stream>() != null);
Contract.EndContractBlock();
// If the WinRT stream is actually a wrapped managed stream, we will unwrap it and return the original.
// In that case we do not need to put the wrapper into the map.
// We currently do capability-based adapter selection for WinRt->NetFx, but not vice versa (time constraints).
// Once we added the reverse direction, we will be able replce this entire section with just a few lines.
NetFxToWinRtStreamAdapter sAdptr = windowsRuntimeStream as NetFxToWinRtStreamAdapter;
if (sAdptr != null)
{
Stream wrappedNetFxStream = sAdptr.GetManagedStream();
if (wrappedNetFxStream == null)
{
throw new ObjectDisposedException(nameof(windowsRuntimeStream), SR.ObjectDisposed_CannotPerformOperation);
}
#if DEBUG // In Chk builds, verify that the original managed stream is correctly entered into the NetFx->WinRT map:
AssertMapContains(s_netFxToWinRtAdapterMap, wrappedNetFxStream, sAdptr,
valueMayBeWrappedInBufferedStream: false);
#endif // DEBUG
return(wrappedNetFxStream);
}
// We have a real WinRT stream.
Stream adapter;
bool adapterExists = s_winRtToNetFxAdapterMap.TryGetValue(windowsRuntimeStream, out adapter);
// There is already an adapter:
if (adapterExists)
{
Debug.Assert((adapter is BufferedStream && ((BufferedStream)adapter).UnderlyingStream is WinRtToNetFxStreamAdapter) ||
(adapter is WinRtToNetFxStreamAdapter));
if (forceBufferSize)
{
EnsureAdapterBufferSize(adapter, bufferSize, invokedMethodName);
}
return(adapter);
}
// We do not have an adapter for this WinRT stream yet and we need to create one.
// Do that in a thread-safe manner in a separate method such that we only have to pay for the compiler allocating
// the required closure if this code path is hit:
return(AsStreamInternalFactoryHelper(windowsRuntimeStream, bufferSize, invokedMethodName, forceBufferSize));
}