diff --git a/Tests/IPAddressTests/IPAddressTests.cs b/Tests/IPAddressTests/IPAddressTests.cs index f89b18e..dcbec9e 100644 --- a/Tests/IPAddressTests/IPAddressTests.cs +++ b/Tests/IPAddressTests/IPAddressTests.cs @@ -16,7 +16,7 @@ namespace NFUnitTestIPAddress public class IPAddressTests { [Setup] - public void SetupConnectToEthernetTests() + public void Setup() { // Comment next line to run the tests on a real hardware Assert.SkipTest("Skipping tests using nanoCLR Win32 in a pipeline"); @@ -301,5 +301,24 @@ public void NetTest6_SocketAddressBasic() + " as " + socketAddress2.ToString() + " " + socketAddress2.GetHashCode()); } } + + [TestMethod] + public void Equality_Tests() + { + var privateAddress = IPAddress.Parse("192.168.0.1"); + var publicAddress = IPAddress.Parse("1.1.1.1"); + + // Equal + Assert.AreEqual(privateAddress, IPAddress.Parse("192.168.0.1")); + Assert.AreEqual(publicAddress, IPAddress.Parse("1.1.1.1")); + Assert.IsTrue(privateAddress == new IPAddress(new byte[] { 192, 168, 0, 1 }), "192.168.0.1 == 192.168.0.1"); + Assert.IsTrue(publicAddress == new IPAddress(new byte[] { 1, 1, 1, 1 }), "1.1.1.1 == 1.1.1.1"); + + // Not Equal + Assert.AreNotEqual(privateAddress, IPAddress.Parse("1.1.1.1")); + Assert.AreNotEqual(publicAddress, IPAddress.Parse("192.168.0.1")); + Assert.IsTrue(privateAddress != new IPAddress(new byte[] { 192, 168, 0, 2 }), "192.168.0.1 == 192.168.0.2"); + Assert.IsTrue(publicAddress != new IPAddress(new byte[] { 1, 1, 1, 2 }), "1.1.1.1 == 1.1.1.2"); + } } } diff --git a/Tests/IPAddressTests/IPAddressTests.nfproj b/Tests/IPAddressTests/IPAddressTests.nfproj index aa2f4ef..fea9537 100644 --- a/Tests/IPAddressTests/IPAddressTests.nfproj +++ b/Tests/IPAddressTests/IPAddressTests.nfproj @@ -61,6 +61,9 @@ + + + diff --git a/Tests/IPAddressTests/nano.runsettings b/Tests/IPAddressTests/nano.runsettings index e82b99e..93ce85e 100644 --- a/Tests/IPAddressTests/nano.runsettings +++ b/Tests/IPAddressTests/nano.runsettings @@ -2,14 +2,16 @@ - 1 .\TestResults 120000 net48 x64 - None - False + None + False + COM3 + + \ No newline at end of file diff --git a/nanoFramework.System.Net/IPAddress.cs b/nanoFramework.System.Net/IPAddress.cs index ed091f8..c698710 100644 --- a/nanoFramework.System.Net/IPAddress.cs +++ b/nanoFramework.System.Net/IPAddress.cs @@ -24,12 +24,38 @@ public class IPAddress /// /// Provides an IP address that indicates that the server must listen for client activity on all network interfaces. This field is read-only. /// - public static readonly IPAddress Any = new(0x0000000000000000); + /// + /// The method uses the field to indicate that a instance must listen for client activity on all network interfaces. + /// + /// The field is equivalent to 0.0.0.0 in dotted-quad notation. + /// + public static readonly IPAddress Any = new(new byte[] { 0, 0, 0, 0 }); /// /// Provides the IP loopback address. This field is read-only. /// - public static readonly IPAddress Loopback = new(0x000000000100007F); + /// + /// The field is equivalent to 127.0.0.1 in dotted-quad notation. + /// + public static readonly IPAddress Loopback = new(new byte[] { 127, 0, 0, 1 }); + + /// + /// Provides the IP broadcast address. This field is read-only. + /// + /// + /// The field is equivalent to 255.255.255.255 in dotted-quad notation. + /// + public static readonly IPAddress Broadcast = new(new byte[] { 255, 255, 255, 255 }); + + /// + /// Provides an IP address that indicates that no network interface should be used. This field is read-only. + /// + /// + /// The uses the field to indicate that a must not listen for client activity. + /// + /// The field is equivalent to 255.255.255.255 in dotted-quad notation. + /// + public static readonly IPAddress None = Broadcast; internal readonly long Address; @@ -136,6 +162,22 @@ public IPAddress(byte[] address) } } + /// + /// Indicates whether two objects are equal. + /// + /// The to compare with . + /// The to compare with . + /// if is equal to ; otherwise, . + public static bool operator ==(IPAddress a, IPAddress b) => a is not null && a.Equals(b); + + /// + /// Indicates whether two objects are not equal. + /// + /// The to compare with . + /// The to compare with . + /// if is not equal to ; otherwise, . + public static bool operator !=(IPAddress a, IPAddress b) => !(a == b); + /// /// Initializes a new instance of a IPV6 class with the address specified as a Byte array. /// @@ -173,16 +215,33 @@ private IPAddress(ushort[] address, uint scopeid) /// /// Compares two IP addresses. /// - /// An instance to compare to the current instance. - /// - public override bool Equals(object obj) + /// An instance to compare to the current instance. + /// if the two addresses are equal; otherwise, . + public override bool Equals(object other) { - IPAddress addr = obj as IPAddress; + return other is IPAddress ipAddress && Equals(ipAddress); + } - if (obj == null) return false; + /// + /// Compares two IP addresses. + /// + /// An instance to compare to the current instance. + /// if the two addresses are equal; otherwise, . + public bool Equals(IPAddress other) + { + if (other is null) + { + return false; + } + + // Compare families before address representations + if (AddressFamily != other.AddressFamily) + { + return false; + } // Compare family before address - if (_family != addr.AddressFamily) + if (_family != other.AddressFamily) { return false; } @@ -190,28 +249,25 @@ public override bool Equals(object obj) if (_family == AddressFamily.InterNetworkV6) { // For IPv6 addresses, compare the full 128bit address - for (int i = 0; i < NumberOfLabels; i++) + for (var i = 0; i < NumberOfLabels; i++) { - if (addr._numbers[i] != this._numbers[i]) + if (other._numbers[i] != _numbers[i]) return false; } // Also scope must match - if (addr._scopeid == this._scopeid) - return true; - - return false; + return other._scopeid == _scopeid; } else { - return this.Address == addr.Address; + return Address == other.Address; } } /// - /// Provides a copy of the as an array of bytes. + /// Provides a copy of the as an array of bytes in network order. /// - /// A Byte array. + /// A array. public byte[] GetAddressBytes() { byte[] bytes; @@ -223,8 +279,8 @@ public byte[] GetAddressBytes() int j = 0; for (int i = 0; i < NumberOfLabels; i++) { - bytes[j++] = (byte)((this._numbers[i] >> 8) & 0xFF); - bytes[j++] = (byte)((this._numbers[i]) & 0xFF); + bytes[j++] = (byte)((_numbers[i] >> 8) & 0xFF); + bytes[j++] = (byte)((_numbers[i]) & 0xFF); } return bytes; } @@ -341,11 +397,9 @@ public override int GetHashCode() { return ToString().GetHashCode(); } - else - { - // For IPv4 addresses, we can simply use the integer representation. - return unchecked((int)Address); - } + + // For IPv4 addresses, we can simply use the integer representation. + return unchecked((int)Address); } // For security, we need to be able to take an IPAddress and make a copy that's immutable and not derived. @@ -410,7 +464,7 @@ public IPAddress MapToIPv6() return this; } - ushort[] labels = new ushort[IPAddress.NumberOfLabels]; + ushort[] labels = new ushort[NumberOfLabels]; labels[5] = 0xFFFF; labels[6] = (ushort)(((Address & 0x0000FF00) >> 8) | ((Address & 0x000000FF) << 8)); labels[7] = (ushort)(((Address & 0xFF000000) >> 24) | ((Address & 0x00FF0000) >> 8)); diff --git a/nanoFramework.System.Net/Properties/AssemblyInfo.cs b/nanoFramework.System.Net/Properties/AssemblyInfo.cs index 6f37577..7638b29 100644 --- a/nanoFramework.System.Net/Properties/AssemblyInfo.cs +++ b/nanoFramework.System.Net/Properties/AssemblyInfo.cs @@ -11,7 +11,7 @@ //////////////////////////////////////////////////////////////// // update this whenever the native assembly signature changes // -[assembly: AssemblyNativeVersion("100.2.0.0")] +[assembly: AssemblyNativeVersion("100.2.0.1")] //////////////////////////////////////////////////////////////// // Setting ComVisible to false makes the types in this assembly not visible