|
8 | 8 | namespace System.Net.Http
|
9 | 9 | {
|
10 | 10 | // This helper class is used to copy the content of a source stream to a destination stream.
|
11 |
| - // The type verifies if the source and/or destination stream are MemoryStreams (or derived types). If so, sync |
| 11 | + // The type verifies if the source and/or destination stream are MemoryStreams (or derived types). If so, sync |
12 | 12 | // read/write is used on the MemoryStream to avoid context switches.
|
13 |
| - internal class StreamToStreamCopy |
| 13 | + internal static class StreamToStreamCopy |
14 | 14 | {
|
15 |
| - private byte[] _buffer; |
16 |
| - private int _bufferSize; |
17 |
| - private Stream _source; |
18 |
| - private Stream _destination; |
19 |
| - private bool _disposeSource; |
20 |
| - private bool _sourceIsMemoryStream; |
21 |
| - private bool _destinationIsMemoryStream; |
22 |
| - |
23 |
| - public StreamToStreamCopy(Stream source, Stream destination, int bufferSize, bool disposeSource) |
| 15 | + public static async Task CopyAsync(Stream source, Stream destination, int bufferSize, bool disposeSource) |
24 | 16 | {
|
25 | 17 | Contract.Requires(source != null);
|
26 | 18 | Contract.Requires(destination != null);
|
27 | 19 | Contract.Requires(bufferSize > 0);
|
28 | 20 |
|
29 |
| - _buffer = new byte[bufferSize]; |
30 |
| - _source = source; |
31 |
| - _destination = destination; |
32 |
| - _bufferSize = bufferSize; |
33 |
| - _disposeSource = disposeSource; |
34 |
| - _sourceIsMemoryStream = source is MemoryStream; |
35 |
| - _destinationIsMemoryStream = destination is MemoryStream; |
36 |
| - } |
| 21 | + byte[] buffer = new byte[bufferSize]; |
37 | 22 |
|
38 |
| - public async Task StartAsync() |
39 |
| - { |
40 | 23 | // If both streams are MemoryStreams, just copy the whole content at once to avoid context switches.
|
41 | 24 | // This will not block since it will just result in a memcopy.
|
42 |
| - if (_sourceIsMemoryStream && _destinationIsMemoryStream) |
| 25 | + if (source is MemoryStream && destination is MemoryStream) |
43 | 26 | {
|
44 | 27 | for (; ;)
|
45 | 28 | {
|
46 |
| - int bytesRead = _source.Read(_buffer, 0, _bufferSize); |
| 29 | + int bytesRead = source.Read(buffer, 0, bufferSize); |
47 | 30 | if (bytesRead == 0)
|
48 | 31 | break;
|
49 |
| - _destination.Write(_buffer, 0, bytesRead); |
| 32 | + destination.Write(buffer, 0, bytesRead); |
50 | 33 | }
|
51 | 34 | }
|
52 | 35 | else
|
53 | 36 | {
|
54 | 37 | for (; ;)
|
55 | 38 | {
|
56 |
| - int bytesRead = await _source.ReadAsync(_buffer, 0, _bufferSize).ConfigureAwait(false); |
| 39 | + int bytesRead = await source.ReadAsync(buffer, 0, bufferSize).ConfigureAwait(false); |
57 | 40 | if (bytesRead == 0)
|
58 | 41 | break;
|
59 |
| - await _destination.WriteAsync(_buffer, 0, bytesRead).ConfigureAwait(false); |
| 42 | + await destination.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false); |
60 | 43 | }
|
61 | 44 | }
|
62 | 45 |
|
63 | 46 | try
|
64 | 47 | {
|
65 |
| - if (_disposeSource) |
| 48 | + if (disposeSource) |
66 | 49 | {
|
67 |
| - _source.Dispose(); |
| 50 | + source.Dispose(); |
68 | 51 | }
|
69 | 52 | }
|
70 | 53 | catch (Exception e)
|
71 | 54 | {
|
72 | 55 | // Dispose() should never throw, but since we're on an async codepath, make sure to catch the exception.
|
73 |
| - if (Logging.On) Logging.Exception(Logging.Http, this, "SetCompleted", e); |
| 56 | + if (Logging.On) Logging.Exception(Logging.Http, null, "CopyAsync", e); |
74 | 57 | }
|
75 | 58 | }
|
76 | 59 | }
|
|
0 commit comments