System.Uri.ParseSchemeCheckImplicitFile C# (CSharp) Method

ParseSchemeCheckImplicitFile() static private method

static private ParseSchemeCheckImplicitFile ( char uriString, ushort length, ParsingError &err, Flags &flags, UriParser &syntax ) : ushort
uriString char
length ushort
err ParsingError
flags Flags
syntax UriParser
return ushort
        unsafe static private ushort ParseSchemeCheckImplicitFile(char* uriString, ushort length,
            ref ParsingError err, ref Flags flags, ref UriParser syntax)
        {
            ushort idx = 0;

            //skip whitespace
            while (idx < length && UriHelper.IsLWS(uriString[idx]))
            {
                ++idx;
            }

            // sets the recognizer for well known registered schemes
            // file, ftp, http, https, uuid, etc
            // Note that we don't support one-letter schemes that will be put into a DOS path bucket

            ushort end = idx;
            while (end < length && uriString[end] != ':')
            {
                ++end;
            }

            // NB: On 64-bits we will use less optimized code from CheckSchemeSyntax()
            //
            if (IntPtr.Size == 4)
            {
                // long = 4chars: The minimal size of a known scheme is 2 + ':'
                if (end != length && end >= idx + 2 &&
                    CheckKnownSchemes((long*)(uriString + idx), (ushort)(end - idx), ref syntax))
                {
                    return (ushort)(end + 1);
                }
            }

            //NB: A string must have at least 3 characters and at least 1 before ':'
            if (idx + 2 >= length || end == idx)
            {
                err = ParsingError.BadFormat;
                return 0;
            }

            //Check for supported special cases like a DOS file path OR a UNC share path
            //NB: A string may not have ':' if this is a UNC path
            {
                char c;
                if ((c = uriString[idx + 1]) == ':' || c == '|')
                {
                    //DOS-like path?
                    if (UriHelper.IsAsciiLetter(uriString[idx]))
                    {
                        if ((c = uriString[idx + 2]) == '\\' || c == '/')
                        {
                            flags |= (Flags.DosPath | Flags.ImplicitFile | Flags.AuthorityFound);
                            syntax = UriParser.FileUri;
                            return idx;
                        }
                        err = ParsingError.MustRootedPath;
                        return 0;
                    }
                    if (c == ':')
                        err = ParsingError.BadScheme;
                    else
                        err = ParsingError.BadFormat;
                    return 0;
                }
                else if ((c = uriString[idx]) == '/' || c == '\\')
                {
                    //UNC share ?
                    if ((c = uriString[idx + 1]) == '\\' || c == '/')
                    {
                        flags |= (Flags.UncPath | Flags.ImplicitFile | Flags.AuthorityFound);
                        syntax = UriParser.FileUri;
                        idx += 2;
                        // V1.1 compat this will simply eat any slashes prepended to a UNC path
                        while (idx < length && ((c = uriString[idx]) == '/' || c == '\\'))
                            ++idx;

                        return idx;
                    }
                    err = ParsingError.BadFormat;
                    return 0;
                }
            }

            if (end == length)
            {
                err = ParsingError.BadFormat;
                return 0;
            }

            // Here could be a possibly valid, and not well-known scheme
            // Finds the scheme delimiter
            // we don;t work with the schemes names > c_MaxUriSchemeName (should be ~1k)
            if ((end - idx) > c_MaxUriSchemeName)
            {
                err = ParsingError.SchemeLimit;
                return 0;
            }

            //Check the syntax, canonicalize  and avoid a GC call
            char* schemePtr = stackalloc char[end - idx];
            for (length = 0; idx < end; ++idx)
            {
                schemePtr[length++] = uriString[idx];
            }
            err = CheckSchemeSyntax(schemePtr, length, ref syntax);
            if (err != ParsingError.None)
            {
                return 0;
            }
            return (ushort)(end + 1);
        }