Example #1
0
        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);
        }
Example #2
0
        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);
            }
        }