4
4
using System ;
5
5
using System . Buffers ;
6
6
using System . IO . Pipelines ;
7
- using System . Text ;
8
- using System . Runtime . CompilerServices ;
9
- using System . Runtime . InteropServices ;
10
7
11
8
namespace Microsoft . AspNetCore . Server . Kestrel . Core . Internal . Http
12
9
{
13
10
internal static class ChunkWriter
14
11
{
15
- // 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
16
- 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' } ;
17
-
18
12
public static int BeginChunkBytes ( int dataCount , Span < byte > span )
19
13
{
20
14
// Determine the most-significant non-zero nibble
@@ -29,14 +23,17 @@ public static int BeginChunkBytes(int dataCount, Span<byte> span)
29
23
30
24
count = ( total >> 2 ) + 3 ;
31
25
32
- var offset = 0 ;
33
- ref var startHex = ref MemoryMarshal . GetReference ( Hex ) ;
26
+ // This must be explicity typed as ReadOnlySpan<byte>
27
+ // It then becomes a non-allocating mapping to the data section of the assembly.
28
+ // For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static
29
+ 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' } ;
34
30
31
+ var offset = 0 ;
35
32
for ( shift = total ; shift >= 0 ; shift -= 4 )
36
33
{
37
- // Using Unsafe.Add to elide the bounds check on _hex as the & 0x0f definitely
38
- // constrains it to the range 0x0 - 0xf, matching the bounds of the array
39
- span [ offset ] = Unsafe . Add ( ref startHex , ( ( dataCount >> shift ) & 0x0f ) ) ;
34
+ // Uses dotnet/runtime#1644 to elide the bounds check on hex as the & 0x0f definitely
35
+ // constrains it to the range 0x0 - 0xf, matching the bounds of the array.
36
+ span [ offset ] = hex [ ( dataCount >> shift ) & 0x0f ] ;
40
37
offset ++ ;
41
38
}
42
39
0 commit comments