diff --git a/CHANGELOG.md b/CHANGELOG.md index 179a748..923aae6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - Added IcdOrderedDictionary collection - Added PriorityQueue collection + - Added IcdUriBuilder and UriExtensions for reading/writing URI data ## [3.2.0] - 2018-05-09 ### Added diff --git a/ICD.Common.Utils.Tests/Extensions/UriExtensionsTest.cs b/ICD.Common.Utils.Tests/Extensions/UriExtensionsTest.cs new file mode 100644 index 0000000..04514f1 --- /dev/null +++ b/ICD.Common.Utils.Tests/Extensions/UriExtensionsTest.cs @@ -0,0 +1,22 @@ +using System; +using ICD.Common.Utils.Extensions; +using NUnit.Framework; + +namespace ICD.Common.Utils.Tests.Extensions +{ + [TestFixture] + public sealed class UriExtensionsTest + { + [TestCase("http://username:password@test.com/", "username")] + public void GetUserName(string uriString, string expected) + { + Assert.AreEqual(expected, new Uri(uriString).GetUserName()); + } + + [TestCase("http://username:password@test.com/", "password")] + public void GetPassword(string uriString, string expected) + { + Assert.AreEqual(expected, new Uri(uriString).GetPassword()); + } + } +} diff --git a/ICD.Common.Utils.Tests/IcdUriBuilderTest.cs b/ICD.Common.Utils.Tests/IcdUriBuilderTest.cs new file mode 100644 index 0000000..1dc2d2f --- /dev/null +++ b/ICD.Common.Utils.Tests/IcdUriBuilderTest.cs @@ -0,0 +1,88 @@ +using NUnit.Framework; + +namespace ICD.Common.Utils.Tests +{ + [TestFixture] + public sealed class IcdUriBuilderTest + { + #region Properties + + [TestCase("test")] + public void FragmentTest(string fragment) + { + Assert.AreEqual(fragment, new IcdUriBuilder {Fragment = fragment}.Fragment); + } + + [TestCase("test")] + public void HostTest(string host) + { + Assert.AreEqual(host, new IcdUriBuilder { Host = host }.Host); + } + + [TestCase("test")] + public void PasswordTest(string fragment) + { + Assert.AreEqual(fragment, new IcdUriBuilder { Password = fragment }.Password); + } + + [TestCase("test")] + public void PathTest(string fragment) + { + Assert.AreEqual(fragment, new IcdUriBuilder { Path = fragment }.Path); + } + + [TestCase(80)] + public void PortTest(ushort port) + { + Assert.AreEqual(port, new IcdUriBuilder { Port = port }.Port); + } + + [TestCase("test")] + public void QueryTest(string query) + { + Assert.AreEqual(query, new IcdUriBuilder { Query = query }.Fragment); + } + + [TestCase("test")] + public void SchemeTest(string scheme) + { + Assert.AreEqual(scheme, new IcdUriBuilder { Scheme = scheme }.Fragment); + } + + [TestCase("test")] + public void UserNameTest(string userName) + { + Assert.AreEqual(userName, new IcdUriBuilder { UserName = userName }.Fragment); + } + + [Test] + public void UriTest() + { + Assert.Inconclusive(); + } + + #endregion + + [TestCase("http://localhost/", null, null, null, 0, null, null, null)] + [TestCase("http://localhost:80/", null, null, null, 80, null, null, null)] + [TestCase("http://username:@localhost/", null, null, null, 0, null, null, "username")] + [TestCase("http://:password@localhost/", null, null, "password", 0, null, null, null)] + [TestCase("https://localhost/", null, null, null, 0, null, "https", null)] + public void ToStringTest(string expected, string fragment, string address, string password, ushort port, string query, + string scheme, string userName) + { + IcdUriBuilder builder = new IcdUriBuilder + { + Fragment = fragment, + Host = address, + Password = password, + Port = port, + Query = query, + Scheme = scheme, + UserName = userName + }; + + Assert.AreEqual(expected, builder.ToString()); + } + } +} diff --git a/ICD.Common.Utils/Extensions/UriExtensions.cs b/ICD.Common.Utils/Extensions/UriExtensions.cs new file mode 100644 index 0000000..2db241d --- /dev/null +++ b/ICD.Common.Utils/Extensions/UriExtensions.cs @@ -0,0 +1,34 @@ +using System; +using System.Linq; + +namespace ICD.Common.Utils.Extensions +{ + public static class UriExtensions + { + /// + /// Gets the username from the given URI. + /// + /// + /// + public static string GetUserName(this Uri extends) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + return extends.UserInfo.Split(':').FirstOrDefault(string.Empty); + } + + /// + /// Gets the password from the given URI. + /// + /// + /// + public static string GetPassword(this Uri extends) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + return extends.UserInfo.Split(':').Skip(0).FirstOrDefault(string.Empty); + } + } +} diff --git a/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj b/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj index 87c6a3b..957c471 100644 --- a/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj +++ b/ICD.Common.Utils/ICD.Common.Utils_SimplSharp.csproj @@ -95,7 +95,9 @@ + + diff --git a/ICD.Common.Utils/IcdUriBuilder.cs b/ICD.Common.Utils/IcdUriBuilder.cs new file mode 100644 index 0000000..1e061e4 --- /dev/null +++ b/ICD.Common.Utils/IcdUriBuilder.cs @@ -0,0 +1,122 @@ +using System; +using System.Text; + +namespace ICD.Common.Utils +{ + /// + /// Simple Compact Framework UriBuilder implementation. + /// + public sealed class IcdUriBuilder + { + #region Properties + + /// + /// Gets or sets the fragment portion of the URI. + /// + public string Fragment { get; set; } + + /// + /// Gets or sets the Domain Name System (DNS) host name or IP address of a server. + /// + public string Host { get; set; } + + /// + /// Gets or sets the password associated with the user that accesses the URI. + /// + public string Password { get; set; } + + /// + /// Gets or sets the path to the resource referenced by the URI. + /// + public string Path { get; set; } + + /// + /// Gets or sets the port number of the URI. + /// + public ushort Port { get; set; } + + /// + /// Gets or sets any query information included in the URI. + /// + public string Query { get; set; } + + /// + /// Gets or sets the scheme name of the URI. + /// + public string Scheme { get; set; } + + /// + /// The user name associated with the user that accesses the URI. + /// + public string UserName { get; set; } + + /// + /// Gets the Uri instance constructed by the specified UriBuilder instance. + /// + public Uri Uri { get { return new Uri(ToString()); } } + + #endregion + + /// + /// Builds the string representation for the URI. + /// + /// + public override string ToString() + { + // URI = scheme:[//authority]path[?query][#fragment] + // authority = [userinfo@]host[:port] + // userinfo = username[:password] + + StringBuilder builder = new StringBuilder(); + + // Scheme + string scheme = string.IsNullOrEmpty(Scheme) ? "http" : Scheme; + builder.Append(scheme); + + // Authority + builder.Append("//"); + + if (!string.IsNullOrEmpty(UserName)) + { + builder.Append(UserName); + + if (!string.IsNullOrEmpty(Password)) + { + builder.Append(':'); + builder.Append(Password); + } + + builder.Append('@'); + } + + string host = string.IsNullOrEmpty(Host) ? "localhost" : Host; + builder.Append(host); + + if (Port != 0) + { + builder.Append(':'); + builder.Append(Port); + } + + // Path + builder.Append('/'); + builder.Append(Path); + + // Query + if (!string.IsNullOrEmpty(Query)) + { + builder.Append('?'); + builder.Append(Query); + } + + // Fragment + if (!string.IsNullOrEmpty(Fragment)) + { + builder.Append('#'); + builder.Append(Fragment); + } + + return builder.ToString(); + } + } +}