public static int NeedsEscaping(ReadOnlySpan <char> value, JavaScriptEncoder encoder) { if (encoder != null) { return(encoder.FindFirstCharacterToEncodeUtf8(MemoryMarshal.Cast <char, byte>(value))); } int idx; for (idx = 0; idx < value.Length; idx++) { if (NeedsEscaping(value[idx])) { goto Return; } } idx = -1; // all characters allowed Return: return(idx); }
public static int NeedsEscaping(ReadOnlySpan <byte> value, JavaScriptEncoder encoder) { int idx; if (encoder != null) { idx = encoder.FindFirstCharacterToEncodeUtf8(value); 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 <byte> value, JavaScriptEncoder encoder) { fixed(byte *ptr = value) { int idx = 0; if (encoder != null) { idx = encoder.FindFirstCharacterToEncodeUtf8(value); goto Return; } #if BUILDING_INBOX_LIBRARY if (Sse2.IsSupported) { sbyte *startingAddress = (sbyte *)ptr; while (value.Length - 16 >= idx) { Debug.Assert(startingAddress >= ptr && startingAddress <= (ptr + value.Length - 16)); // Load the next 16 bytes. Vector128 <sbyte> sourceValue = Sse2.LoadVector128(startingAddress); // Check if any of the 16 bytes need to be escaped. Vector128 <sbyte> mask = CreateEscapingMask(sourceValue); int index = Sse2.MoveMask(mask.AsByte()); // If index == 0, that means none of the 16 bytes needed to be escaped. // TrailingZeroCount is relatively expensive, avoid it if possible. if (index != 0) { // Found at least one byte that needs to be escaped, figure out the index of // the first one found that needed to be escaped within the 16 bytes. Debug.Assert(index > 0 && index <= 65_535); int tzc = BitOperations.TrailingZeroCount(index); Debug.Assert(tzc >= 0 && tzc <= 16); idx += tzc; goto Return; } idx += 16; startingAddress += 16; } // Process the remaining characters. Debug.Assert(value.Length - idx < 16); } #endif for (; idx < value.Length; idx++) { Debug.Assert((ptr + idx) <= (ptr + value.Length)); if (NeedsEscaping(*(ptr + idx))) { goto Return; } } idx = -1; // all characters allowed Return: return(idx); } }