Skip to content

Commit

Permalink
Remove Unsafe from ChunkWriter (#18450)
Browse files Browse the repository at this point in the history
  • Loading branch information
benaadams authored and jkotalik committed Jan 22, 2020
1 parent bc60e95 commit 2127e5d
Showing 1 changed file with 8 additions and 11 deletions.
19 changes: 8 additions & 11 deletions src/Servers/Kestrel/Core/src/Internal/Http/ChunkWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@
using System;
using System.Buffers;
using System.IO.Pipelines;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{
internal static class ChunkWriter
{
// This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static
private static ReadOnlySpan<byte> Hex => new byte[16] { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' };

public static int BeginChunkBytes(int dataCount, Span<byte> span)
{
// Determine the most-significant non-zero nibble
Expand All @@ -29,14 +23,17 @@ public static int BeginChunkBytes(int dataCount, Span<byte> span)

count = (total >> 2) + 3;

var offset = 0;
ref var startHex = ref MemoryMarshal.GetReference(Hex);
// This must be explicity typed as ReadOnlySpan<byte>
// It then becomes a non-allocating mapping to the data section of the assembly.
// For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static
ReadOnlySpan<byte> hex = new byte[16] { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' };

var offset = 0;
for (shift = total; shift >= 0; shift -= 4)
{
// Using Unsafe.Add to elide the bounds check on _hex as the & 0x0f definitely
// constrains it to the range 0x0 - 0xf, matching the bounds of the array
span[offset] = Unsafe.Add(ref startHex, ((dataCount >> shift) & 0x0f));
// Uses dotnet/runtime#1644 to elide the bounds check on hex as the & 0x0f definitely
// constrains it to the range 0x0 - 0xf, matching the bounds of the array.
span[offset] = hex[(dataCount >> shift) & 0x0f];
offset++;
}

Expand Down

0 comments on commit 2127e5d

Please sign in to comment.