-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
StreamWrapper.cs
113 lines (90 loc) · 2.43 KB
/
StreamWrapper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using System;
using System.IO;
#if !NETSTANDARD1_0
using System.Net.Http;
#endif
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms
{
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("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);
}
#if !NETSTANDARD1_0
public static async Task<Stream> GetStreamAsync(Uri uri, CancellationToken cancellationToken, HttpClient client)
{
HttpResponseMessage response = await client.GetAsync(uri, cancellationToken).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
Internals.Log.Warning("HTTP Request", $"Could not retrieve {uri}, status code {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);
}
#endif
}
}