/// <summary> /// Create the external version of a uri /// </summary> private static string _asFormatted(DocumentUri uri, bool skipEncoding) { string Encoder(string p, bool allowSlash) { return(!skipEncoding?EncodeUriComponentFast(p, allowSlash) : EncodeUriComponentMinimal(p)); } var res = ""; var(scheme, authority, path, query, fragment) = uri; if (!string.IsNullOrWhiteSpace(scheme)) { res += scheme; res += ":"; } if (!string.IsNullOrWhiteSpace(authority) || scheme == "file") { res += Slash; res += Slash; } if (!string.IsNullOrWhiteSpace(authority)) { var idx = authority.IndexOf("@"); if (idx != -1) { // <user>@<auth> var userinfo = authority.Substring(0, idx); authority = authority.Substring(idx + 1); idx = userinfo.IndexOf(":"); if (idx == -1) { res += Encoder(userinfo, false); } else { // <user>:<pass>@<auth> res += Encoder(userinfo.Substring(0, idx), false); res += ":"; res += Encoder(userinfo.Substring(idx + 1), false); } res += "@"; } authority = authority.ToLowerInvariant(); idx = authority.IndexOf(":", StringComparison.Ordinal); if (idx == -1) { res += Encoder(authority, false); } else { // <auth>:<port> res += Encoder(authority.Substring(0, idx), false); res += authority.Substring(idx); } } if (!string.IsNullOrWhiteSpace(path)) { // lower-case windows drive letters in /C:/fff or C:/fff if (path.Length >= 3 && path[0] == CharCode.Slash && path[2] == CharCode.Colon) { var code = path[1]; if (code >= CharCode.A && code <= CharCode.Z) { path = $"/{Convert.ToChar(code + 32)}:{path.Substring(3)}"; // "/c:".length == 3 } } else if (path.Length >= 2 && path[1] == CharCode.Colon) { var code = path[0]; if (code >= CharCode.A && code <= CharCode.Z) { path = $"{Convert.ToChar(code + 32)}:{path.Substring(2)}"; // "/c:".length == 3 } } // encode the rest of the path res += Encoder(path, true); } if (!string.IsNullOrWhiteSpace(query)) { res += "?"; res += Encoder(query, false); } if (!string.IsNullOrWhiteSpace(fragment)) { res += "#"; res += !skipEncoding?EncodeUriComponentFast(fragment, false) : fragment; } return(res); }