Skip to content

Commit

Permalink
Use GC.AllocateUninitializedArray in MemoryStream.ToArray (#50692)
Browse files Browse the repository at this point in the history
* Use GC.AllocateUninitializedArray in MemoryStream.ToArray

* Apply suggestions from code review

Co-authored-by: Stephen Toub <[email protected]>

Co-authored-by: Stephen Toub <[email protected]>
  • Loading branch information
bbowyersmyth and stephentoub authored Apr 5, 2021
1 parent 84bf5bc commit c5eeedb
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Xunit;
using System;
using System.IO;
using System.Collections.Generic;
using System.Security.Cryptography;

namespace System.IO.Tests
{
public class MemoryStream_ToArrayTests
{
[Theory]
[MemberData(nameof(GetArraysVariedBySize))]
public static void ToArray_ZeroOffset(byte[] array)
{
var stream = new MemoryStream();
stream.Write(array);
var newArray = stream.ToArray();

Assert.Equal(array.Length, newArray.Length);
Assert.Equal(array, newArray);
}

[Theory]
[MemberData(nameof(GetArraysVariedBySize))]
public static void ToArray_Offset(byte[] array)
{
int index = 0;
int count = array.Length;

if (count > 3)
{
// Trim some off each end
index = 1;
count -= 3;
}

var stream = new MemoryStream(array, index, count);
var newArray = stream.ToArray();

Assert.Equal(count, newArray.Length);
Assert.True(array.AsSpan(index, count).SequenceEqual(newArray));
}

public static IEnumerable<object[]> GetArraysVariedBySize()
{
yield return new object[] { RandomNumberGenerator.GetBytes(0) };
yield return new object[] { RandomNumberGenerator.GetBytes(1) };
yield return new object[] { RandomNumberGenerator.GetBytes(2) };
yield return new object[] { RandomNumberGenerator.GetBytes(256) };
yield return new object[] { RandomNumberGenerator.GetBytes(512) };
yield return new object[] { RandomNumberGenerator.GetBytes(1024) };
yield return new object[] { RandomNumberGenerator.GetBytes(2047) };
yield return new object[] { RandomNumberGenerator.GetBytes(2048) };
yield return new object[] { RandomNumberGenerator.GetBytes(2049) };
yield return new object[] { RandomNumberGenerator.GetBytes(2100) };
}
}
}
1 change: 1 addition & 0 deletions src/libraries/System.IO/tests/System.IO.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<Compile Include="IndentedTextWriter.cs" />
<Compile Include="BinaryReader\BinaryReaderTests.cs" />
<Compile Include="MemoryStream\MemoryStream.ToArrayTests.cs" />
<Compile Include="MemoryStream\MemoryStream.GetBufferTests.cs" />
<Compile Include="StreamReader\StreamReader.cs" />
<Compile Include="StreamReader\StreamReader.StringCtorTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,8 @@ public virtual byte[] ToArray()
int count = _length - _origin;
if (count == 0)
return Array.Empty<byte>();
byte[] copy = new byte[count];
Buffer.BlockCopy(_buffer, _origin, copy, 0, count);
byte[] copy = GC.AllocateUninitializedArray<byte>(count);
_buffer.AsSpan(_origin, count).CopyTo(copy);
return copy;
}

Expand Down

0 comments on commit c5eeedb

Please sign in to comment.