private static bool ParseHost (ParserState state)
{
string part = state.remaining;
if (state.elements.scheme == Uri.UriSchemeFile && part.Length >= 2 &&
(part [0] == '\\' || part [0] == '/') && part [1] == part [0]) {
part = part.TrimStart (part [0]);
state.remaining = part;
}
if (!ParseWindowsFilePath (state))
return false;
StringBuilder sb = new StringBuilder ();
var tmpHost = "";
var possibleIpv6 = false;
int index;
for (index = 0; index < part.Length; index++) {
char ch = part [index];
if (ch == '/' || ch == '#' || ch == '?')
break;
// Possible IPv6
if (string.IsNullOrEmpty (tmpHost) && ch == ':') {
tmpHost = sb.ToString ();
possibleIpv6 = true;
}
sb.Append (ch);
if (possibleIpv6 && ch == ']')
break;
}
if (possibleIpv6) {
IPv6Address ipv6addr;
if (IPv6Address.TryParse (sb.ToString (), out ipv6addr)) {
#if NET_4_5
var ipStr = ipv6addr.ToString (false);
#else
var ipStr = ipv6addr.ToString (true);
#endif
//remove scope
ipStr = ipStr.Split ('%') [0];
state.elements.host = "[" + ipStr + "]";
state.elements.scopeId = ipv6addr.ScopeId;
state.remaining = part.Substring (sb.Length);
return state.remaining.Length > 0;
}
state.elements.host = tmpHost;
} else
state.elements.host = sb.ToString ();
state.elements.host = state.elements.host.ToLowerInvariant ();
state.remaining = part.Substring (state.elements.host.Length);
if (state.elements.scheme == Uri.UriSchemeFile &&
state.elements.host != "") {
// under Windows all file://host URI are considered UNC, which is not the case other MacOS (e.g. Silverlight)
#if BOOTSTRAP_BASIC
state.elements.isUnc = (Path.DirectorySeparatorChar == '\\');
#else
state.elements.isUnc = Environment.IsRunningOnWindows;
#endif
}
return state.remaining.Length > 0;
}