| File: BlockingMemoryStream.cs | Web Access |
| Project: src\sdk\src\Cli\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj (Microsoft.DotNet.Cli.Utils) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Concurrent; namespace Microsoft.DotNet.Cli.Utils; /// <summary> /// An in-memory stream that will block any read calls until something was written to it. /// </summary> public sealed class BlockingMemoryStream : Stream { private readonly BlockingCollection<byte[]> _buffers = []; private ArraySegment<byte> _remaining; public override void Write(byte[] buffer, int offset, int count) { byte[] tmp = new byte[count]; Buffer.BlockCopy(buffer, offset, tmp, 0, count); _buffers.Add(tmp); } public override int Read(byte[] buffer, int offset, int count) { if (count == 0) { return 0; } if (_remaining.Count == 0) { if (!_buffers.TryTake(out byte[]? tmp, Timeout.Infinite) || tmp.Length == 0) { return 0; } _remaining = new ArraySegment<byte>(tmp, 0, tmp.Length); } if (_remaining.Array is not null) { if (_remaining.Count <= count) { count = _remaining.Count; Buffer.BlockCopy(_remaining.Array, _remaining.Offset, buffer, offset, count); _remaining = default; } else { Buffer.BlockCopy(_remaining.Array, _remaining.Offset, buffer, offset, count); _remaining = new ArraySegment<byte>(_remaining.Array, _remaining.Offset + count, _remaining.Count - count); } } return count; } public void DoneWriting() { _buffers.CompleteAdding(); } protected override void Dispose(bool disposing) { if (disposing) { _buffers.Dispose(); } base.Dispose(disposing); } public override bool CanRead => true; public override bool CanSeek => false; public override bool CanWrite => true; public override long Length { get { throw new NotImplementedException(); } } public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public override void Flush() { } public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } public override void SetLength(long value) { throw new NotImplementedException(); } }