// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #if NETSTANDARD2_1_OR_GREATER using System; using System.IO; using System.Threading; using System.Threading.Tasks; namespace CommunityToolkit.HighPerformance.Streams; /// internal partial class MemoryStream { /// public sealed override void CopyTo(Stream destination, int bufferSize) { MemoryStream.ValidateDisposed(this.disposed); Span source = this.source.Span.Slice(this.position); this.position += source.Length; destination.Write(source); } /// public sealed override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { return new ValueTask(Task.FromCanceled(cancellationToken)); } try { int result = Read(buffer.Span); return new ValueTask(result); } catch (OperationCanceledException e) { return new ValueTask(Task.FromCanceled(e.CancellationToken)); } catch (Exception e) { return new ValueTask(Task.FromException(e)); } } /// public sealed override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { return new ValueTask(Task.FromCanceled(cancellationToken)); } try { Write(buffer.Span); return default; } catch (OperationCanceledException e) { return new ValueTask(Task.FromCanceled(e.CancellationToken)); } catch (Exception e) { return new ValueTask(Task.FromException(e)); } } /// public sealed override int Read(Span buffer) { MemoryStream.ValidateDisposed(this.disposed); int bytesAvailable = this.source.Length - this.position, bytesCopied = Math.Min(bytesAvailable, buffer.Length); Span source = this.source.Span.Slice(this.position, bytesCopied); source.CopyTo(buffer); this.position += bytesCopied; return bytesCopied; } /// public sealed override void Write(ReadOnlySpan buffer) { MemoryStream.ValidateDisposed(this.disposed); MemoryStream.ValidateCanWrite(CanWrite); Span destination = this.source.Span.Slice(this.position); if (!buffer.TryCopyTo(destination)) { MemoryStream.ThrowArgumentExceptionForEndOfStreamOnWrite(); } this.position += buffer.Length; } } #endif