public static bool TryParseComponents (string uri, UriKind kind, out UriElements elements, out string error)
{
uri = uri.Trim ();
ParserState state = new ParserState (uri, kind);
elements = state.elements;
error = null;
if (uri.Length == 0 && (kind == UriKind.Relative || kind == UriKind.RelativeOrAbsolute)){
state.elements.isAbsoluteUri = false;
return true;
}
if (uri.Length <= 1 && kind == UriKind.Absolute) {
error = "Absolute URI is too short";
return false;
}
bool ok = ParseFilePath (state) &&
ParseScheme (state);
var scheme = state.elements.scheme;
UriParser parser = null;
if (!string.IsNullOrEmpty (scheme)) {
parser = UriParser.GetParser (scheme);
if (parser != null && !(parser is DefaultUriParser))
return true;
}
ok = ok &&
ParseAuthority (state) &&
ParsePath (state) &&
ParseQuery (state) &&
ParseFragment (state);
if (string.IsNullOrEmpty (state.elements.host) &&
(scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeGopher || scheme == Uri.UriSchemeNntp ||
scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp))
state.error = "Invalid URI: The Authority/Host could not be parsed.";
if (!string.IsNullOrEmpty (state.elements.host) &&
Uri.CheckHostName (state.elements.host) == UriHostNameType.Unknown)
state.error = "Invalid URI: The hostname could not be parsed.";
if (!string.IsNullOrEmpty (state.error)) {
elements = null;
error = state.error;
return false;
}
return true;
}