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();
}
}