< Summary

Information
Class: System.Net.Http.StreamToStreamCopy
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\StreamToStreamCopy.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 49
Coverable lines: 49
Total lines: 109
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 14
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
Copy(...)0%440%
CopyAsync(...)0%880%
DisposeSourceAsync()100%110%
DisposeSource(...)0%220%

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\StreamToStreamCopy.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Diagnostics;
 5using System.IO;
 6using System.Threading;
 7using System.Threading.Tasks;
 8
 9namespace System.Net.Http
 10{
 11    /// <summary>
 12    /// Helper class is used to copy the content of a source stream to a destination stream,
 13    /// with optimizations based on expected usage within HttpClient and with the ability
 14    /// to dispose of the source stream when the copy has completed.
 15    /// </summary>
 16    internal static class StreamToStreamCopy
 17    {
 18        /// <summary>Copies the source stream from its current position to the destination stream at its current positio
 19        /// <param name="source">The source stream from which to copy.</param>
 20        /// <param name="destination">The destination stream to which to copy.</param>
 21        /// <param name="bufferSize">The size of the buffer to allocate if one needs to be allocated. If zero, use the d
 22        /// <param name="disposeSource">Whether to dispose of the source stream after the copy has finished successfully
 23        public static void Copy(Stream source, Stream destination, int bufferSize, bool disposeSource)
 024        {
 025            Debug.Assert(source != null);
 026            Debug.Assert(destination != null);
 027            Debug.Assert(bufferSize >= 0);
 28
 029            if (bufferSize == 0)
 030            {
 031                source.CopyTo(destination);
 032            }
 33            else
 034            {
 035                source.CopyTo(destination, bufferSize);
 036            }
 37
 038            if (disposeSource)
 039            {
 040                DisposeSource(source);
 041            }
 042        }
 43
 44        /// <summary>Copies the source stream from its current position to the destination stream at its current positio
 45        /// <param name="source">The source stream from which to copy.</param>
 46        /// <param name="destination">The destination stream to which to copy.</param>
 47        /// <param name="bufferSize">The size of the buffer to allocate if one needs to be allocated. If zero, use the d
 48        /// <param name="disposeSource">Whether to dispose of the source stream after the copy has finished successfully
 49        /// <param name="cancellationToken">CancellationToken used to cancel the copy operation.</param>
 50        public static Task CopyAsync(Stream source, Stream destination, int bufferSize, bool disposeSource, Cancellation
 051        {
 052            Debug.Assert(source != null);
 053            Debug.Assert(destination != null);
 054            Debug.Assert(bufferSize >= 0);
 55
 56            try
 057            {
 058                Task copyTask = bufferSize == 0 ?
 059                    source.CopyToAsync(destination, cancellationToken) :
 060                    source.CopyToAsync(destination, bufferSize, cancellationToken);
 61
 062                if (!disposeSource)
 063                {
 064                    return copyTask;
 65                }
 66
 067                switch (copyTask.Status)
 68                {
 69                    case TaskStatus.RanToCompletion:
 070                        DisposeSource(source);
 071                        return Task.CompletedTask;
 72
 73                    case TaskStatus.Faulted:
 74                    case TaskStatus.Canceled:
 075                        return copyTask;
 76
 77                    default:
 078                        return DisposeSourceAsync(copyTask, source);
 79
 80                        static async Task DisposeSourceAsync(Task copyTask, Stream source)
 081                        {
 082                            await copyTask.ConfigureAwait(false);
 083                            DisposeSource(source);
 084                        }
 85                }
 86            }
 087            catch (Exception e)
 088            {
 89                // For compatibility with the previous implementation, catch everything (including arg exceptions) and
 90                // store errors into the task rather than letting them propagate to the synchronous caller.
 091                return Task.FromException(e);
 92            }
 093        }
 94
 95        /// <summary>Disposes the source stream.</summary>
 96        private static void DisposeSource(Stream source)
 097        {
 98            try
 099            {
 0100                source.Dispose();
 0101            }
 0102            catch (Exception e)
 0103            {
 104                // Dispose() should never throw, but since we're on an async codepath, make sure to catch the exception.
 0105                if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(null, e);
 0106            }
 0107        }
 108    }
 109}