using System.Collections.Generic; using System.Collections.Specialized; using System.Web; namespace Dalamud.Networking.Pipes; /// /// A Dalamud Uri, in the format: /// dalamud://{NAMESPACE}/{ARBITRARY} /// public record DalamudUri { private readonly Uri rawUri; private DalamudUri(Uri uri) { if (uri.Scheme != "dalamud") { throw new ArgumentOutOfRangeException(nameof(uri), "URI must be of scheme dalamud."); } this.rawUri = uri; } /// /// Gets the namespace that this URI should be routed to. Generally a high level component like "PluginInstaller". /// public string Namespace => this.rawUri.Authority; /// /// Gets the raw (untargeted) path and query params for this URI. /// public string Data => this.rawUri.GetComponents(UriComponents.PathAndQuery | UriComponents.Fragment, UriFormat.UriEscaped); /// /// Gets the raw (untargeted) path for this URI. /// public string Path => this.rawUri.AbsolutePath; /// /// Gets a list of segments based on the provided Data element. /// public string[] Segments => this.GetDataSegments(); /// /// Gets the raw query parameters for this URI, if any. /// public string Query => this.rawUri.Query; /// /// Gets the query params (as a parsed NameValueCollection) in this URI. /// public NameValueCollection QueryParams => HttpUtility.ParseQueryString(this.Query); /// /// Gets the fragment (if one is specified) in this URI. /// public string Fragment => this.rawUri.Fragment; /// public override string ToString() => this.rawUri.ToString(); /// /// Build a DalamudURI from a given URI. /// /// The URI to convert to a Dalamud URI. /// Returns a DalamudUri. public static DalamudUri FromUri(Uri uri) { return new DalamudUri(uri); } /// /// Build a DalamudURI from a URI in string format. /// /// The URI to convert to a Dalamud URI. /// Returns a DalamudUri. public static DalamudUri FromUri(string uri) => FromUri(new Uri(uri)); private string[] GetDataSegments() { // reimplementation of the System.URI#Segments, under MIT license. var path = this.Path; var segments = new List(); var current = 0; while (current < path.Length) { var next = path.IndexOf('/', current); if (next == -1) { next = path.Length - 1; } segments.Add(path.Substring(current, (next - current) + 1)); current = next + 1; } return segments.ToArray(); } }