// /** // * File: URI.cs // * Author: haraldwolff // * // * This file and it's content is copyrighted by the Author and / or copyright holder. // * Any use wihtout proper permission is illegal and may lead to legal actions. // * // * // **/ using System; using System.Text; namespace ln.type { /** * Quick and Dirty RFC3986 URI * **/ public class URI { public String Scheme { get; private set; } = String.Empty; public String Authority { get; private set; } = String.Empty; public String[] UserInfo { get; private set; } = new String[0]; public String Host { get; private set; } = String.Empty; public String Port { get; private set; } = String.Empty; public String Path { get; private set; } = String.Empty; public String Query { get; private set; } = String.Empty; public String Fragment { get; private set; } = String.Empty; private URI() { } public URI(String uri) { Parse(uri); ParseAuthority(); } public URI(String scheme, String authority, string path) { Parse(String.Format("{0}://{1}{2}", scheme, authority, path)); ParseAuthority(); } public URI(String scheme,String authority,string path,string query,string fragment) { Scheme = scheme; Authority = authority; Path = path; Query = query; Fragment = fragment; ParseAuthority(); } public URI(URI uri, string path) { Parse(String.Format("{0}://{1}{2}", uri.Scheme, uri.Authority, path)); ParseAuthority(); } public URI Follow(String path) { if (path.StartsWith("/",StringComparison.InvariantCulture)) { return new URI(Scheme, Authority, path); } else if (Path.EndsWith("/",StringComparison.InvariantCulture) || path.StartsWith("?",StringComparison.InvariantCulture) || path.StartsWith("#", StringComparison.InvariantCulture)) { return new URI(Scheme, Authority, String.Format("{0}{1}", Path, path)); } else { int indSlash = Path.LastIndexOf('/'); return new URI(Scheme, Authority, String.Format("{0}/{1}",Path.Substring(0,indSlash),path)); } } private void Parse(String uri) { char[] chUri = uri.ToCharArray(); int n = 0; int m = 0; // Scheme while ((chUri[n] != ':') && ((++n) < chUri.Length)) { }; if (n < 2) throw new FormatException(String.Format("URL malformed: {0}",uri)); Scheme = new string(chUri, 0, n); n++; if (n < chUri.Length) { if ((chUri.Length - n > 1) && (chUri[n] == '/') && (chUri[n+1] == '/')) { // Authority n += 2; m = n; while ( (m < chUri.Length) && (chUri[m] != '/') && (chUri[m] != '?') && (chUri[m] != '#') ) { m++; } Authority = new string(chUri, n, (m - n)); n = m; } // Path m = n; while ( (m < chUri.Length) && (chUri[m] != '?') && (chUri[m] != '#') ) { m++; } Path = new string(chUri, n, (m - n)); n = m; if (n < chUri.Length) { if (chUri[n] == '?') { n++; m = n; while ( (m < chUri.Length) && (chUri[m] != '#') ) { m++; } Query = new string(chUri, n, (m - n)); n = m; } if ((n 0) { stringBuilder.Append(UserInfo[0]); stringBuilder.Append('@'); } stringBuilder.Append(Host); if (!String.Empty.Equals(Port)) { stringBuilder.Append(':'); stringBuilder.Append(Port); } } stringBuilder.Append(Path); if (!string.Empty.Equals(Query)) { stringBuilder.Append("?"); stringBuilder.Append(Query); } if (!string.Empty.Equals(Fragment)) { stringBuilder.Append('#'); stringBuilder.Append(Fragment); } return stringBuilder.ToString(); } private int GetHashCode(String s) { return (s == null) ? -1 : s.GetHashCode(); } public override int GetHashCode() { return GetHashCode(Scheme) ^ GetHashCode(Authority) ^ GetHashCode(Path) ^ GetHashCode(Query) ^ GetHashCode(Fragment); } public override bool Equals(object obj) { if (obj is URI) { URI other = obj as URI; return Scheme.Equals(other.Scheme) && Authority.Equals(other.Authority) && Path.Equals(other.Path) && Query.Equals(other.Query) && Fragment.Equals(other.Fragment); } return false; } } }