System.Uri.CombineUri C# (CSharp) Method

CombineUri() private static method

private static CombineUri ( Uri basePart, string relativePart, UriFormat uriFormat ) : string
basePart Uri
relativePart string
uriFormat UriFormat
return string
        private static string CombineUri(Uri basePart, string relativePart, UriFormat uriFormat)
        {
            //NB: relativePart is ensured as not empty by the caller
            //    Another assumption is that basePart is an AbsoluteUri

            // This method was not optimized for efficiency
            // Means a relative Uri ctor may be relatively slow plus it increases the footprint of the baseUri

            char c1 = relativePart[0];

            //check a special case for the base as DOS path and a rooted relative string
            if (basePart.IsDosPath &&
                (c1 == '/' || c1 == '\\') &&
                (relativePart.Length == 1 || (relativePart[1] != '/' && relativePart[1] != '\\')))
            {
                // take relative part appended to the base string after the drive letter
                int idx = basePart.OriginalString.IndexOf(':');
                if (basePart.IsImplicitFile)
                {
                    return basePart.OriginalString.Substring(0, idx + 1) + relativePart;
                }
                // The basePart has explicit scheme (could be not file:), take the DOS drive ':' position
                idx = basePart.OriginalString.IndexOf(':', idx + 1);
                return basePart.OriginalString.Substring(0, idx + 1) + relativePart;
            }

            // Check special case for Unc or absolute path in relativePart when base is FILE
            if (StaticIsFile(basePart.Syntax))
            {
                if (c1 == '\\' || c1 == '/')
                {
                    if (relativePart.Length >= 2 && (relativePart[1] == '\\' || relativePart[1] == '/'))
                    {
                        //Assuming relative is a Unc path and base is a file uri.
                        return basePart.IsImplicitFile ? relativePart : "file:" + relativePart;
                    }

                    // here we got an absolute path in relativePart,
                    // For compatibility with V1.0 parser we restrict the compression scope to Unc Share, i.e. \\host\share\
                    if (basePart.IsUnc)
                    {
                        string share = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter,
                            UriFormat.Unescaped);
                        for (int i = 1; i < share.Length; ++i)
                        {
                            if (share[i] == '/')
                            {
                                share = share.Substring(0, i);
                                break;
                            }
                        }
                        if (basePart.IsImplicitFile)
                        {
                            return @"\\"
                                    + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped)
                                    + share
                                    + relativePart;
                        }
                        return "file://"
                                + basePart.GetParts(UriComponents.Host, uriFormat)
                                + share
                                + relativePart;
                    }
                    // It's not obvious but we've checked (for this relativePart format) that baseUti is nor UNC nor DOS path
                    //
                    // Means base is a Unix style path and, btw, IsImplicitFile cannot be the case either
                    return "file://" + relativePart;
                }
            }

            // If we are here we did not recognize absolute DOS/UNC path for a file: base uri
            // Note that DOS path may still happen in the relativePart and if so it may override the base uri scheme.

            bool convBackSlashes = basePart.Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes);

            string left = null;

            // check for network or local absolute path
            if (c1 == '/' || (c1 == '\\' && convBackSlashes))
            {
                if (relativePart.Length >= 2 && relativePart[1] == '/')
                {
                    // got an authority in relative path and the base scheme is not file (checked)
                    return basePart.Scheme + ':' + relativePart;
                }

                // Got absolute relative path, and the base is nor FILE nor a DOS path (checked at the method start)
                if (basePart.HostType == Flags.IPv6HostType)
                {
                    left = basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo, uriFormat)
                                     + '[' + basePart.DnsSafeHost + ']'
                                     + basePart.GetParts(UriComponents.KeepDelimiter | UriComponents.Port, uriFormat);
                }
                else
                {
                    left = basePart.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, uriFormat);
                }

                if (convBackSlashes && c1 == '\\')
                    relativePart = '/' + relativePart.Substring(1);

                return left + relativePart;
            }

            // Here we got a relative path
            // Need to run path Compression because this is how relative Uri combining works

            // Take the base part path up to and including the last slash
            left = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter,
                basePart.IsImplicitFile ? UriFormat.Unescaped : uriFormat);
            int length = left.Length;
            char[] path = new char[length + relativePart.Length];

            if (length > 0)
            {
                left.CopyTo(0, path, 0, length);
                while (length > 0)
                {
                    if (path[--length] == '/')
                    {
                        ++length;
                        break;
                    }
                }
            }

            //Append relative path to the result
            relativePart.CopyTo(0, path, length, relativePart.Length);

            // Split relative on path and extra (for compression)
            c1 = basePart.Syntax.InFact(UriSyntaxFlags.MayHaveQuery) ? '?' : c_DummyChar;

            // The  implicit file check is to avoid a fragment in the implicit file combined uri.
            char c2 = (!basePart.IsImplicitFile && basePart.Syntax.InFact(UriSyntaxFlags.MayHaveFragment)) ? '#' :
                c_DummyChar;
            string extra = string.Empty;

            // assuming c_DummyChar may not happen in an unicode uri string
            if (!(c1 == c_DummyChar && c2 == c_DummyChar))
            {
                int i = 0;
                for (; i < relativePart.Length; ++i)
                {
                    if (path[length + i] == c1 || path[length + i] == c2)
                    {
                        break;
                    }
                }
                if (i == 0)
                {
                    extra = relativePart;
                }
                else if (i < relativePart.Length)
                {
                    extra = relativePart.Substring(i);
                }
                length += i;
            }
            else
            {
                length += relativePart.Length;
            }

            // Take the base part up to the path
            if (basePart.HostType == Flags.IPv6HostType)
            {
                if (basePart.IsImplicitFile)
                {
                    left = @"\\[" + basePart.DnsSafeHost + ']';
                }
                else
                {
                    left = basePart.GetParts(UriComponents.Scheme | UriComponents.UserInfo, uriFormat)
                            + '[' + basePart.DnsSafeHost + ']'
                            + basePart.GetParts(UriComponents.KeepDelimiter | UriComponents.Port, uriFormat);
                }
            }
            else
            {
                if (basePart.IsImplicitFile)
                {
                    if (basePart.IsDosPath)
                    {
                        // The FILE DOS path comes as /c:/path, we have to exclude first 3 chars from compression
                        path = Compress(path, 3, ref length, basePart.Syntax);
                        return new string(path, 1, length - 1) + extra;
                    }
                    else
                    {
                        left = @"\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped);
                    }
                }
                else
                {
                    left = basePart.GetParts(UriComponents.SchemeAndServer | UriComponents.UserInfo, uriFormat);
                }
            }
            //compress the path
            path = Compress(path, basePart.SecuredPathIndex, ref length, basePart.Syntax);
            return left + new string(path, 0, length) + extra;
        }