Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Use string.Create in BitConverter.ToString(byte[]) #15218

Merged
merged 1 commit into from
Nov 26, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 17 additions & 42 deletions src/mscorlib/shared/System/BitConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,17 +354,6 @@ public static double ToDouble(ReadOnlySpan<byte> value)
return Unsafe.ReadUnaligned<double>(ref value.DangerousGetPinnableReference());
}

private static char GetHexValue(int i)
{
Debug.Assert(i >= 0 && i < 16, "i is out of range.");
if (i < 10)
{
return (char)(i + '0');
}

return (char)(i - 10 + 'A');
}

// Converts an array of bytes into a String.
public static string ToString(byte[] value, int startIndex, int length)
{
Expand All @@ -388,41 +377,27 @@ public static string ToString(byte[] value, int startIndex, int length)
throw new ArgumentOutOfRangeException(nameof(length), SR.Format(SR.ArgumentOutOfRange_LengthTooLarge, (int.MaxValue / 3)));
}

int chArrayLength = length * 3;
const int StackLimit = 512; // arbitrary limit to switch from stack to heap allocation
unsafe
return string.Create(length * 3 - 1, (value, startIndex, length), (dst, state) =>
{
if (chArrayLength < StackLimit)
{
char* chArrayPtr = stackalloc char[chArrayLength];
return ToString(value, startIndex, length, chArrayPtr, chArrayLength);
}
else
{
char[] chArray = new char[chArrayLength];
fixed (char* chArrayPtr = &chArray[0])
return ToString(value, startIndex, length, chArrayPtr, chArrayLength);
}
}
}
const string HexValues = "0123456789ABCDEF";

private static unsafe string ToString(byte[] value, int startIndex, int length, char* chArray, int chArrayLength)
{
Debug.Assert(length > 0);
Debug.Assert(chArrayLength == length * 3);
var src = new ReadOnlySpan<byte>(state.value, state.startIndex, state.length);

char* p = chArray;
int endIndex = startIndex + length;
for (int i = startIndex; i < endIndex; i++)
{
byte b = value[i];
*p++ = GetHexValue(b >> 4);
*p++ = GetHexValue(b & 0xF);
*p++ = '-';
}
int i = 0;
int j = 0;

byte b = src[i++];
dst[j++] = HexValues[b >> 4];
dst[j++] = HexValues[b & 0xF];

// We don't need the last '-' character
return new string(chArray, 0, chArrayLength - 1);
while (i < src.Length)
{
b = src[i++];
dst[j++] = '-';
dst[j++] = HexValues[b >> 4];
dst[j++] = HexValues[b & 0xF];
}
});
}

// Converts an array of bytes into a String.
Expand Down