< Summary - Jellyfin

Information
Class: Jellyfin.LiveTv.IO.StreamHelper
Assembly: Jellyfin.LiveTv
File(s): /srv/git/jellyfin/src/Jellyfin.LiveTv/IO/StreamHelper.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 42
Coverable lines: 42
Total lines: 120
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 18
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 4/19/2026 - 12:14:27 AM Line coverage: 0% (0/42) Branch coverage: 0% (0/18) Total lines: 120 4/19/2026 - 12:14:27 AM Line coverage: 0% (0/42) Branch coverage: 0% (0/18) Total lines: 120

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
CopyToAsync()0%2040%
CopyToAsync()0%7280%
CopyUntilCancelled()0%2040%
CopyToAsyncInternal()0%620%

File(s)

/srv/git/jellyfin/src/Jellyfin.LiveTv/IO/StreamHelper.cs

#LineLine coverage
 1#pragma warning disable CS1591
 2
 3using System;
 4using System.Buffers;
 5using System.IO;
 6using System.Threading;
 7using System.Threading.Tasks;
 8using MediaBrowser.Model.IO;
 9
 10namespace Jellyfin.LiveTv.IO
 11{
 12    public class StreamHelper : IStreamHelper
 13    {
 14        public async Task CopyToAsync(Stream source, Stream destination, int bufferSize, Action? onStarted, Cancellation
 15        {
 016            byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
 17            try
 18            {
 19                int read;
 020                while ((read = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) != 0)
 21                {
 022                    cancellationToken.ThrowIfCancellationRequested();
 23
 024                    await destination.WriteAsync(buffer.AsMemory(0, read), cancellationToken).ConfigureAwait(false);
 25
 026                    if (onStarted is not null)
 27                    {
 028                        onStarted();
 029                        onStarted = null;
 30                    }
 31                }
 032            }
 33            finally
 34            {
 035                ArrayPool<byte>.Shared.Return(buffer);
 36            }
 037        }
 38
 39        public async Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, Cancellatio
 40        {
 041            byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
 42            try
 43            {
 044                if (emptyReadLimit <= 0)
 45                {
 46                    int read;
 047                    while ((read = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) != 0)
 48                    {
 049                        cancellationToken.ThrowIfCancellationRequested();
 50
 051                        await destination.WriteAsync(buffer.AsMemory(0, read), cancellationToken).ConfigureAwait(false);
 52                    }
 53
 054                    return;
 55                }
 56
 057                var eofCount = 0;
 58
 059                while (eofCount < emptyReadLimit)
 60                {
 061                    cancellationToken.ThrowIfCancellationRequested();
 62
 063                    var bytesRead = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);
 64
 065                    if (bytesRead == 0)
 66                    {
 067                        eofCount++;
 068                        await Task.Delay(50, cancellationToken).ConfigureAwait(false);
 69                    }
 70                    else
 71                    {
 072                        eofCount = 0;
 73
 074                        await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(fa
 75                    }
 76                }
 077            }
 78            finally
 79            {
 080                ArrayPool<byte>.Shared.Return(buffer);
 81            }
 082        }
 83
 84        public async Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellatio
 85        {
 086            byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
 87            try
 88            {
 089                while (!cancellationToken.IsCancellationRequested)
 90                {
 091                    var bytesRead = await CopyToAsyncInternal(source, target, buffer, cancellationToken).ConfigureAwait(
 92
 093                    if (bytesRead == 0)
 94                    {
 095                        await Task.Delay(100, cancellationToken).ConfigureAwait(false);
 96                    }
 97                }
 098            }
 99            finally
 100            {
 0101                ArrayPool<byte>.Shared.Return(buffer);
 102            }
 0103        }
 104
 105        private static async Task<int> CopyToAsyncInternal(Stream source, Stream destination, byte[] buffer, Cancellatio
 106        {
 107            int bytesRead;
 0108            int totalBytesRead = 0;
 109
 0110            while ((bytesRead = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) != 0)
 111            {
 0112                await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
 113
 0114                totalBytesRead += bytesRead;
 115            }
 116
 0117            return totalBytesRead;
 0118        }
 119    }
 120}