File: src\Servers\Kestrel\shared\test\StreamExtensions.cs
Web Access
Project: src\src\Servers\Kestrel\Transport.Quic\test\Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Tests.csproj (Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Threading;
using System.Threading.Tasks;
using Xunit;
 
namespace System.IO;
 
public static class StreamExtensions
{
    /// <summary>
    /// Fill the buffer until the end of the stream.
    /// </summary>
    public static async Task<int> FillBufferUntilEndAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default)
    {
        var offset = 0;
        int read;
 
        do
        {
            read = await stream.ReadAsync(buffer, offset, buffer.Length - offset, cancellationToken);
            offset += read;
        } while (read != 0 && offset < buffer.Length);
 
        if (read != 0)
        {
            Assert.Equal(0, await stream.ReadAsync(new byte[1], 0, 1, cancellationToken));
        }
 
        return offset;
    }
 
    public static async Task<int> FillEntireBufferAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default)
    {
        var offset = 0;
        int read;
 
        do
        {
            read = await stream.ReadAsync(buffer, offset, buffer.Length - offset, cancellationToken);
            offset += read;
        } while (read != 0 && offset < buffer.Length);
 
        Assert.True(offset >= buffer.Length);
        return offset;
    }
 
    public static async Task<byte[]> ReadAtLeastLengthAsync(this Stream stream, int length, int bufferLength = 1024, bool allowEmpty = false, CancellationToken cancellationToken = default)
    {
        var buffer = new byte[bufferLength];
        var data = new List<byte>();
        var offset = 0;
 
        while (offset < length)
        {
            var read = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
            offset += read;
 
            if (read == 0)
            {
                if (allowEmpty && offset == 0)
                {
                    return null;
                }
 
                throw new Exception("Stream read 0.");
            }
 
            data.AddRange(buffer.AsMemory(0, read).ToArray());
        }
 
        return data.ToArray();
    }
 
    public static async Task<byte[]> ReadUntilEndAsync(this Stream stream, int bufferLength = 1024, CancellationToken cancellationToken = default)
    {
        var buffer = new byte[bufferLength];
        var data = new List<byte>();
        var offset = 0;
 
        while (true)
        {
            var read = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
            offset += read;
 
            if (read == 0)
            {
                return data.ToArray();
            }
 
            data.AddRange(buffer.AsMemory(0, read).ToArray());
        }
    }
}