4
4
using System . Diagnostics ;
5
5
using System . Numerics ;
6
6
using System . Runtime . CompilerServices ;
7
+ using System . Runtime . InteropServices ;
7
8
8
9
namespace System . Text . Json
9
10
{
10
11
internal static partial class JsonReaderHelper
11
12
{
12
- private static unsafe int IndexOfOrLessThan ( ref byte searchSpace , byte value0 , byte value1 , byte lessThan , int length )
13
+ /// <summary>IndexOfAny('"', '\', less than 32)</summary>
14
+ /// <remarks>https://tools.ietf.org/html/rfc8259</remarks>
15
+ public static unsafe int IndexOfQuoteOrAnyControlOrBackSlash ( this ReadOnlySpan < byte > span )
13
16
{
17
+ // Borrowed and modified from SpanHelpers.Byte:
18
+ // https://github.com/dotnet/corefx/blob/fc169cddedb6820aaabbdb8b7bece2a3df0fd1a5/src/Common/src/CoreLib/System/SpanHelpers.Byte.cs#L473-L604
19
+
20
+ ref byte searchSpace = ref MemoryMarshal . GetReference ( span ) ;
21
+ int length = span . Length ;
14
22
Debug . Assert ( length >= 0 ) ;
15
23
16
- uint uValue0 = value0 ; // Use uint for comparisons to avoid unnecessary 8->32 extensions
17
- uint uValue1 = value1 ; // Use uint for comparisons to avoid unnecessary 8->32 extensions
18
- uint uLessThan = lessThan ; // Use uint for comparisons to avoid unnecessary 8->32 extensions
24
+ const byte Value0 = JsonConstants . Quote ;
25
+ const byte Value1 = JsonConstants . BackSlash ;
26
+ const byte LessThan = JsonConstants . Space ;
27
+
28
+ const uint UValue0 = Value0 ; // Use uint for comparisons to avoid unnecessary 8->32 extensions
29
+ const uint UValue1 = Value1 ; // Use uint for comparisons to avoid unnecessary 8->32 extensions
30
+ const uint ULessThan = LessThan ; // Use uint for comparisons to avoid unnecessary 8->32 extensions
31
+
19
32
IntPtr index = ( IntPtr ) 0 ; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations
20
33
IntPtr nLength = ( IntPtr ) length ;
21
34
@@ -31,28 +44,28 @@ private static unsafe int IndexOfOrLessThan(ref byte searchSpace, byte value0, b
31
44
nLength -= 8 ;
32
45
33
46
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index ) ;
34
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
47
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
35
48
goto Found ;
36
49
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 1 ) ;
37
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
50
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
38
51
goto Found1 ;
39
52
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 2 ) ;
40
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
53
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
41
54
goto Found2 ;
42
55
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 3 ) ;
43
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
56
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
44
57
goto Found3 ;
45
58
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 4 ) ;
46
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
59
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
47
60
goto Found4 ;
48
61
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 5 ) ;
49
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
62
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
50
63
goto Found5 ;
51
64
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 6 ) ;
52
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
65
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
53
66
goto Found6 ;
54
67
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 7 ) ;
55
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
68
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
56
69
goto Found7 ;
57
70
58
71
index += 8 ;
@@ -63,16 +76,16 @@ private static unsafe int IndexOfOrLessThan(ref byte searchSpace, byte value0, b
63
76
nLength -= 4 ;
64
77
65
78
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index ) ;
66
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
79
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
67
80
goto Found ;
68
81
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 1 ) ;
69
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
82
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
70
83
goto Found1 ;
71
84
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 2 ) ;
72
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
85
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
73
86
goto Found2 ;
74
87
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index + 3 ) ;
75
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
88
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
76
89
goto Found3 ;
77
90
78
91
index += 4 ;
@@ -83,7 +96,7 @@ private static unsafe int IndexOfOrLessThan(ref byte searchSpace, byte value0, b
83
96
nLength -= 1 ;
84
97
85
98
lookUp = Unsafe . AddByteOffset ( ref searchSpace , index ) ;
86
- if ( uValue0 == lookUp || uValue1 == lookUp || uLessThan > lookUp )
99
+ if ( UValue0 == lookUp || UValue1 == lookUp || ULessThan > lookUp )
87
100
goto Found ;
88
101
89
102
index += 1 ;
@@ -94,9 +107,9 @@ private static unsafe int IndexOfOrLessThan(ref byte searchSpace, byte value0, b
94
107
nLength = ( IntPtr ) ( ( length - ( int ) ( byte * ) index ) & ~ ( Vector < byte > . Count - 1 ) ) ;
95
108
96
109
// Get comparison Vector
97
- Vector < byte > values0 = new Vector < byte > ( value0 ) ;
98
- Vector < byte > values1 = new Vector < byte > ( value1 ) ;
99
- Vector < byte > valuesLessThan = new Vector < byte > ( lessThan ) ;
110
+ Vector < byte > values0 = new Vector < byte > ( Value0 ) ;
111
+ Vector < byte > values1 = new Vector < byte > ( Value1 ) ;
112
+ Vector < byte > valuesLessThan = new Vector < byte > ( LessThan ) ;
100
113
101
114
while ( ( byte * ) nLength > ( byte * ) index )
102
115
{
0 commit comments