Skip to content

Commit

Permalink
Merge pull request #266 from OronDF343/add-memorystream-copytoasync
Browse files Browse the repository at this point in the history
Asynchronous implementation of `MemorySource<TSource>.CopyToAsync`
  • Loading branch information
Sergio0694 authored Jul 6, 2022
2 parents 43bafc5 + 76e1900 commit 8528092
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,13 @@ public sealed override Task CopyToAsync(Stream destination, int bufferSize, Canc

try
{
CopyTo(destination, bufferSize);
MemoryStream.ValidateDisposed(this.disposed);

return Task.CompletedTask;
Memory<byte> source = this.source.Memory.Slice(this.position);

this.position += source.Length;

return destination.WriteAsync(source, cancellationToken).AsTask();
}
catch (OperationCanceledException e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,11 @@ public Span<byte> Span
#endif
}
}

/// <inheritdoc/>
public Memory<byte> Memory
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => this.array.AsMemory(this.offset, this.length);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ internal interface ISpanOwner
/// Gets a <see cref="Span{T}"/> instance wrapping the underlying memory area.
/// </summary>
Span<byte> Span { get; }

/// <summary>
/// Gets a <see cref="Memory{T}"/> instance wrapping the underlying memory area.
/// </summary>
Memory<byte> Memory { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,11 @@ public Span<byte> Span
return this.memoryManager.GetSpan().Slice(this.offset, this.length);
}
}

/// <inheritdoc/>
public Memory<byte> Memory
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => this.memoryManager.Memory.Slice(this.offset, this.length);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,66 @@ public async Task Test_MemoryStream_ReadWriteAsync_Memory()
Assert.IsTrue(data.Span.SequenceEqual(result.Span));
}

[TestMethod]
public void Test_MemoryStream_CopyTo()
{
Stream source = new byte[100].AsMemory().AsStream();

Memory<byte> data = CreateRandomData(64);

source.Write(data.Span);

Assert.AreEqual(source.Position, data.Length);

source.Position = 0;

Stream destination = new byte[100].AsMemory().AsStream();

source.CopyTo(destination);

Assert.AreEqual(source.Position, destination.Position);

destination.Position = 0;

Memory<byte> result = new byte[data.Length];

int bytesRead = destination.Read(result.Span);

Assert.AreEqual(bytesRead, result.Length);
Assert.AreEqual(destination.Position, data.Length);
Assert.IsTrue(data.Span.SequenceEqual(result.Span));
}

[TestMethod]
public async Task Test_MemoryStream_CopyToAsync()
{
Stream source = new byte[100].AsMemory().AsStream();

Memory<byte> data = CreateRandomData(64);

await source.WriteAsync(data);

Assert.AreEqual(source.Position, data.Length);

source.Position = 0;

Stream destination = new byte[100].AsMemory().AsStream();

await source.CopyToAsync(destination);

Assert.AreEqual(source.Position, destination.Position);

destination.Position = 0;

Memory<byte> result = new byte[data.Length];

int bytesRead = await destination.ReadAsync(result);

Assert.AreEqual(bytesRead, result.Length);
Assert.AreEqual(destination.Position, data.Length);
Assert.IsTrue(data.Span.SequenceEqual(result.Span));
}

/// <summary>
/// Creates a random <see cref="byte"/> array filled with random data.
/// </summary>
Expand Down

0 comments on commit 8528092

Please sign in to comment.