System.Uri.CheckCanonical C# (CSharp) Method

CheckCanonical() private method

private CheckCanonical ( char str, ushort &idx, ushort end, char delim ) : Check
str char
idx ushort
end ushort
delim char
return Check
        private unsafe Check CheckCanonical(char* str, ref ushort idx, ushort end, char delim)
        {
            Check res = Check.None;
            bool needsEscaping = false;
            bool foundEscaping = false;

            char c = c_DummyChar;
            ushort i = idx;
            for (; i < end; ++i)
            {
                c = str[i];
                // Control chars usually should be escaped in any case
                if (c <= '\x1F' || (c >= '\x7F' && c <= '\x9F'))
                {
                    needsEscaping = true;
                    foundEscaping = true;
                    res |= Check.ReservedFound;
                }
                else if (c > 'z' && c != '~')
                {
                    if (_iriParsing)
                    {
                        bool valid = false;
                        res |= Check.FoundNonAscii;

                        if (char.IsHighSurrogate(c))
                        {
                            if ((i + 1) < end)
                            {
                                bool surrPair = false;
                                valid = IriHelper.CheckIriUnicodeRange(c, str[i + 1], ref surrPair, true);
                            }
                        }
                        else
                        {
                            valid = IriHelper.CheckIriUnicodeRange(c, true);
                        }
                        if (!valid) res |= Check.NotIriCanonical;
                    }

                    if (!needsEscaping) needsEscaping = true;
                }
                else if (c == delim)
                {
                    break;
                }
                else if (delim == '?' && c == '#' && (_syntax != null && _syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
                {
                    // this is a special case when deciding on Query/Fragment
                    break;
                }
                else if (c == '?')
                {
                    if (IsImplicitFile || (_syntax != null && !_syntax.InFact(UriSyntaxFlags.MayHaveQuery)
                        && delim != c_EOL))
                    {
                        // If found as reserved this char is not suitable for safe unescaped display
                        // Will need to escape it when both escaping and unescaping the string
                        res |= Check.ReservedFound;
                        foundEscaping = true;
                        needsEscaping = true;
                    }
                }
                else if (c == '#')
                {
                    needsEscaping = true;
                    if (IsImplicitFile || (_syntax != null && !_syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
                    {
                        // If found as reserved this char is not suitable for safe unescaped display
                        // Will need to escape it when both escaping and unescaping the string
                        res |= Check.ReservedFound;
                        foundEscaping = true;
                    }
                }
                else if (c == '/' || c == '\\')
                {
                    if ((res & Check.BackslashInPath) == 0 && c == '\\')
                    {
                        res |= Check.BackslashInPath;
                    }
                    if ((res & Check.DotSlashAttn) == 0 && i + 1 != end && (str[i + 1] == '/' || str[i + 1] == '\\'))
                    {
                        res |= Check.DotSlashAttn;
                    }
                }
                else if (c == '.')
                {
                    if ((res & Check.DotSlashAttn) == 0 && i + 1 == end || str[i + 1] == '.' || str[i + 1] == '/'
                        || str[i + 1] == '\\' || str[i + 1] == '?' || str[i + 1] == '#')
                    {
                        res |= Check.DotSlashAttn;
                    }
                }
                else if (!needsEscaping && ((c <= '"' && c != '!') || (c >= '[' && c <= '^') || c == '>'
                    || c == '<' || c == '`'))
                {
                    needsEscaping = true;
                }
                else if (c == '%')
                {
                    if (!foundEscaping) foundEscaping = true;
                    //try unescape a byte hex escaping
                    if (i + 2 < end && (c = UriHelper.EscapedAscii(str[i + 1], str[i + 2])) != c_DummyChar)
                    {
                        if (c == '.' || c == '/' || c == '\\')
                        {
                            res |= Check.DotSlashEscaped;
                        }
                        i += 2;
                        continue;
                    }
                    // otherwise we follow to non escaped case
                    if (!needsEscaping)
                    {
                        needsEscaping = true;
                    }
                }
            }

            if (foundEscaping)
            {
                if (!needsEscaping)
                {
                    res |= Check.EscapedCanonical;
                }
            }
            else
            {
                res |= Check.DisplayCanonical;
                if (!needsEscaping)
                {
                    res |= Check.EscapedCanonical;
                }
            }
            idx = i;
            return res;
        }