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