| File: StreamWrapper.cs | Web Access |
| Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls) |
#nullable disable using System; using System.IO; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace Microsoft.Maui.Controls { internal class StreamWrapper : Stream { readonly Stream _wrapped; IDisposable _additionalDisposable; public StreamWrapper(Stream wrapped) : this(wrapped, null) { } public StreamWrapper(Stream wrapped, IDisposable additionalDisposable) { if (wrapped == null) throw new ArgumentNullException(nameof(wrapped)); _wrapped = wrapped; _additionalDisposable = additionalDisposable; } public override bool CanRead { get { return _wrapped.CanRead; } } public override bool CanSeek { get { return _wrapped.CanSeek; } } public override bool CanWrite { get { return _wrapped.CanWrite; } } public override long Length { get { return _wrapped.Length; } } public override long Position { get { return _wrapped.Position; } set { _wrapped.Position = value; } } public event EventHandler Disposed; public override void Flush() { _wrapped.Flush(); } public override int Read(byte[] buffer, int offset, int count) { return _wrapped.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return _wrapped.Seek(offset, origin); } public override void SetLength(long value) { _wrapped.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { _wrapped.Write(buffer, offset, count); } protected override void Dispose(bool disposing) { _wrapped.Dispose(); Disposed?.Invoke(this, EventArgs.Empty); _additionalDisposable?.Dispose(); _additionalDisposable = null; base.Dispose(disposing); } public static async Task<Stream> GetStreamAsync(Uri uri, CancellationToken cancellationToken, HttpClient client) { var response = await client.GetAsync(uri, cancellationToken).ConfigureAwait(false); if (!response.IsSuccessStatusCode) { Application.Current?.FindMauiContext()?.CreateLogger<StreamWrapper>()? .LogWarning("Could not retrieve {Uri}, status code {StatusCode}", uri, response.StatusCode); return null; } // the HttpResponseMessage needs to be disposed of after the calling code is done with the stream // otherwise the stream may get disposed before the caller can use it return new StreamWrapper(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), response); } } }