MegaBites-AI/Windows-powershell
0308
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#nullable enable5 6using System.Buffers;7using System.IO;8using System.Threading;9using System.Threading.Tasks;10 11namespace System.Management.Automation;12 13/// <summary>14/// Represents the transfer of bytes from one <see cref="Stream" /> to another15/// asynchronously.16/// </summary>17internal sealed class AsyncByteStreamTransfer : IDisposable18{19 private const int DefaultBufferSize = 1024;20 21 private readonly BytePipe _bytePipe;22 23 private readonly BytePipe _destinationPipe;24 25 private readonly Memory<byte> _buffer;26 27 private readonly CancellationTokenSource _cts = new();28 29 private Task? _readToBufferTask;30 31 public AsyncByteStreamTransfer(32 BytePipe bytePipe,33 BytePipe destinationPipe)34 {35 _bytePipe = bytePipe;36 _destinationPipe = destinationPipe;37 _buffer = new byte[DefaultBufferSize];38 }39 40 public Task EOF => _readToBufferTask ?? Task.CompletedTask;41 42 public void BeginReadChunks()43 {44 _readToBufferTask = Task.Run(ReadBufferAsync);45 }46 47 public void Dispose() => _cts.Cancel();48 49 private async Task ReadBufferAsync()50 {51 Stream stream;52 Stream? destinationStream = null;53 try54 {55 stream = await _bytePipe.GetStream(_cts.Token);56 destinationStream = await _destinationPipe.GetStream(_cts.Token);57 58 while (true)59 {60 int bytesRead;61 bytesRead = await stream.ReadAsync(_buffer, _cts.Token);62 if (bytesRead is 0)63 {64 break;65 }66 67 destinationStream.Write(_buffer.Span.Slice(0, bytesRead));68 }69 }70 catch (IOException)71 {72 return;73 }74 catch (OperationCanceledException)75 {76 return;77 }78 finally79 {80 destinationStream?.Close();81 }82 }83}84 