public static unsafe int NeedsEscaping(ReadOnlySpan <char> value, JavaScriptEncoder encoder) { int idx; // Some implementations of JavascriptEncoder.FindFirstCharacterToEncode may not accept // null pointers and gaurd against that. Hence, check up-front and fall down to return -1. if (encoder != null && !value.IsEmpty) { fixed(char *ptr = value) { idx = encoder.FindFirstCharacterToEncode(ptr, value.Length); } goto Return; } for (idx = 0; idx < value.Length; idx++) { if (NeedsEscaping(value[idx])) { goto Return; } } idx = -1; // all characters allowed Return: return(idx); }
public static unsafe int NeedsEscaping(ReadOnlySpan <char> value, JavaScriptEncoder encoder) { fixed(char *ptr = value) { int idx = 0; // Some implementations of JavascriptEncoder.FindFirstCharacterToEncode may not accept // null pointers and gaurd against that. Hence, check up-front and fall down to return -1. if (encoder != null && !value.IsEmpty) { idx = encoder.FindFirstCharacterToEncode(ptr, value.Length); goto Return; } #if BUILDING_INBOX_LIBRARY if (Sse2.IsSupported) { short *startingAddress = (short *)ptr; while (value.Length - 8 >= idx) { Debug.Assert(startingAddress >= ptr && startingAddress <= (ptr + value.Length - 8)); // Load the next 8 characters. Vector128 <short> sourceValue = Sse2.LoadVector128(startingAddress); // Check if any of the 8 characters need to be escaped. Vector128 <short> mask = CreateEscapingMask(sourceValue); int index = Sse2.MoveMask(mask.AsByte()); // If index == 0, that means none of the 8 characters needed to be escaped. // TrailingZeroCount is relatively expensive, avoid it if possible. if (index != 0) { // Found at least one character that needs to be escaped, figure out the index of // the first one found that needed to be escaped within the 8 characters. Debug.Assert(index > 0 && index <= 65_535); int tzc = BitOperations.TrailingZeroCount(index); Debug.Assert(tzc % 2 == 0 && tzc >= 0 && tzc <= 16); idx += tzc >> 1; goto Return; } idx += 8; startingAddress += 8; } // Process the remaining characters. Debug.Assert(value.Length - idx < 8); } #endif for (; idx < value.Length; idx++) { Debug.Assert((ptr + idx) <= (ptr + value.Length)); if (NeedsEscaping(*(ptr + idx))) { goto Return; } } idx = -1; // All characters are allowed. Return: return(idx); } }