internal string GetComponentsHelper(Uri uri, UriComponents components, UriFormat format)
{
UriElements elements = UriParseComponents.ParseComponents(uri.OriginalString.Trim(), UriKind.Absolute);
string scheme = scheme_name;
int dp = default_port;
if ((scheme == null) || (scheme == "*"))
{
scheme = elements.scheme;
dp = Uri.GetDefaultPort(scheme);
}
else if (String.Compare(scheme, elements.scheme, true) != 0)
{
throw new SystemException("URI Parser: scheme mismatch: " + scheme + " vs. " + elements.scheme);
}
var formatFlags = UriHelper.FormatFlags.None;
if (UriHelper.HasCharactersToNormalize(uri.OriginalString))
{
formatFlags |= UriHelper.FormatFlags.HasUriCharactersToNormalize;
}
if (uri.UserEscaped)
{
formatFlags |= UriHelper.FormatFlags.UserEscaped;
}
if (!string.IsNullOrEmpty(elements.host))
{
formatFlags |= UriHelper.FormatFlags.HasHost;
}
// it's easier to answer some case directly (as the output isn't identical
// when mixed with others components, e.g. leading slash, # ...)
switch (components)
{
case UriComponents.Scheme:
return(scheme);
case UriComponents.UserInfo:
return(elements.user ?? "");
case UriComponents.Host:
return(elements.host);
case UriComponents.Port: {
int p = elements.port;
if (p != null && p >= 0 && p != dp)
{
return(p.ToString(CultureInfo.InvariantCulture));
}
return(String.Empty);
}
case UriComponents.Path:
var path = elements.path;
if (scheme != Uri.UriSchemeMailto && scheme != Uri.UriSchemeNews)
{
path = IgnoreFirstCharIf(elements.path, '/');
}
return(UriHelper.FormatAbsolute(path, scheme, UriComponents.Path, format, formatFlags));
case UriComponents.Query:
return(UriHelper.FormatAbsolute(elements.query, scheme, UriComponents.Query, format, formatFlags));
case UriComponents.Fragment:
return(UriHelper.FormatAbsolute(elements.fragment, scheme, UriComponents.Fragment, format, formatFlags));
case UriComponents.StrongPort: {
return(elements.port >= 0
? elements.port.ToString(CultureInfo.InvariantCulture)
: dp.ToString(CultureInfo.InvariantCulture));
}
case UriComponents.SerializationInfoString:
components = UriComponents.AbsoluteUri;
break;
}
// now we deal with multiple flags...
StringBuilder sb = new StringBuilder();
if ((components & UriComponents.Scheme) != 0)
{
sb.Append(scheme);
sb.Append(elements.delimiter);
}
if ((components & UriComponents.UserInfo) != 0)
{
string userinfo = elements.user;
if (userinfo != null)
{
sb.Append(elements.user);
sb.Append('@');
}
}
if ((components & UriComponents.Host) != 0)
{
sb.Append(elements.host);
}
// for StrongPort always show port - even if -1
// otherwise only display if ut's not the default port
if ((components & UriComponents.StrongPort) != 0)
{
sb.Append(":");
if (elements.port >= 0)
{
sb.Append(elements.port);
}
else
{
sb.Append(dp);
}
}
if ((components & UriComponents.Port) != 0)
{
int p = elements.port;
if (p != null && p >= 0 && p != dp)
{
sb.Append(":");
sb.Append(elements.port);
}
}
if ((components & UriComponents.Path) != 0)
{
string path = elements.path;
if ((components & UriComponents.PathAndQuery) != 0 &&
(path.Length == 0 || !path.StartsWith("/", StringComparison.Ordinal)) &&
elements.delimiter == Uri.SchemeDelimiter)
{
sb.Append("/");
}
sb.Append(UriHelper.FormatAbsolute(path, scheme, UriComponents.Path, format, formatFlags));
}
if ((components & UriComponents.Query) != 0)
{
string query = elements.query;
if (query != null)
{
sb.Append("?");
sb.Append(UriHelper.FormatAbsolute(query, scheme, UriComponents.Query, format, formatFlags));
}
}
if ((components & UriComponents.Fragment) != 0)
{
string f = elements.fragment;
if (f != null)
{
sb.Append("#");
sb.Append(UriHelper.FormatAbsolute(f, scheme, UriComponents.Fragment, format, formatFlags));
}
}
return(sb.ToString());
}