Skip to content

Commit 84fa884

Browse files
Add hashCode and equals in IpInterface
1 parent aac86d2 commit 84fa884

File tree

6 files changed

+74
-1
lines changed

6 files changed

+74
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
## NEXT
4+
* Add `hashCode()` and `equals` in `IpInterface`
45

56
## 0.3.0
67
* Add methods in `IpAddressAndPrefix` interface for parsing `ByteArray` representing address and subnet mask in X509 `IpAddressName`

cidre/api/android/cidre.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,15 @@ public abstract class at/asitplus/cidre/IpFamily$RegexSpec {
210210
public abstract class at/asitplus/cidre/IpInterface : at/asitplus/cidre/IpAddressAndPrefix {
211211
public static final field Companion Lat/asitplus/cidre/IpInterface$Companion;
212212
public synthetic fun <init> (ILat/asitplus/cidre/IpNetwork;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
213+
public fun equals (Ljava/lang/Object;)Z
213214
public fun getAddress ()Lat/asitplus/cidre/IpAddress;
214215
public fun getFamily ()Lat/asitplus/cidre/IpFamily;
215216
public fun getHostMask ()[B
216217
public fun getNetmask ()[B
217218
public final fun getNetwork ()Lat/asitplus/cidre/IpNetwork;
218219
public fun getNumberOfHostBits-pVg5ArA ()I
219220
public fun getPrefix-pVg5ArA ()I
221+
public fun hashCode ()I
220222
public fun isLinkLocal ()Z
221223
public fun isLoopback ()Z
222224
public fun isMulticast ()Z

cidre/api/cidre.klib.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ sealed class <#A: kotlin/Number, #B: at.asitplus.cidre.byteops/CidrNumber<#B>> a
331331
open val prefix // at.asitplus.cidre/IpInterface.prefix|{}prefix[0]
332332
open fun <get-prefix>(): kotlin/UInt // at.asitplus.cidre/IpInterface.prefix.<get-prefix>|<get-prefix>(){}[0]
333333

334+
open fun equals(kotlin/Any?): kotlin/Boolean // at.asitplus.cidre/IpInterface.equals|equals(kotlin.Any?){}[0]
335+
open fun hashCode(): kotlin/Int // at.asitplus.cidre/IpInterface.hashCode|hashCode(){}[0]
334336
open fun toString(): kotlin/String // at.asitplus.cidre/IpInterface.toString|toString(){}[0]
335337
open fun toX509Octets(): kotlin/ByteArray // at.asitplus.cidre/IpInterface.toX509Octets|toX509Octets(){}[0]
336338

cidre/api/jvm/cidre.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,15 @@ public abstract class at/asitplus/cidre/IpFamily$RegexSpec {
201201
public abstract class at/asitplus/cidre/IpInterface : at/asitplus/cidre/IpAddressAndPrefix {
202202
public static final field Companion Lat/asitplus/cidre/IpInterface$Companion;
203203
public synthetic fun <init> (ILat/asitplus/cidre/IpNetwork;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
204+
public fun equals (Ljava/lang/Object;)Z
204205
public fun getAddress ()Lat/asitplus/cidre/IpAddress;
205206
public fun getFamily ()Lat/asitplus/cidre/IpFamily;
206207
public fun getHostMask ()[B
207208
public fun getNetmask ()[B
208209
public final fun getNetwork ()Lat/asitplus/cidre/IpNetwork;
209210
public fun getNumberOfHostBits-pVg5ArA ()I
210211
public fun getPrefix-pVg5ArA ()I
212+
public fun hashCode ()I
211213
public fun isLinkLocal ()Z
212214
public fun isLoopback ()Z
213215
public fun isMulticast ()Z

cidre/src/commonMain/kotlin/at/asitplus/cidre/IpInterface.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,28 @@ constructor(override val prefix: Prefix, val network: IpNetwork<N, S>) :
1313
IpAddressAndPrefix<N, S> by network {
1414

1515
override fun toString(): String = "$address/$prefix"
16-
1716
override fun toX509Octets(): ByteArray = super.toX509Octets()
1817

18+
override fun equals(other: Any?): Boolean {
19+
if (this === other) return true
20+
if (other == null || this::class != other::class) return false
21+
22+
other as IpInterface<*, *>
23+
24+
if (prefix != other.prefix) return false
25+
if (network != other.network) return false
26+
if (address != other.address) return false
27+
28+
return true
29+
}
30+
31+
override fun hashCode(): Int {
32+
var result = prefix.hashCode()
33+
result = 31 * result + network.hashCode()
34+
result = 31 * result + address.hashCode()
35+
return result
36+
}
37+
1938
companion object {
2039
@Suppress("UNCHECKED_CAST")
2140
internal fun <N : Number, S: CidrNumber<S>> unsafe(
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import at.asitplus.cidre.IpInterface
2+
import kotlin.test.Test
3+
import kotlin.test.assertEquals
4+
import kotlin.test.assertNotEquals
5+
6+
class IpInterfaceEqualsTest {
7+
8+
@Test
9+
fun `IPv4 equals and hashCode`() {
10+
val ip1 = IpInterface.V4("192.168.1.1/24")
11+
val ip2 = IpInterface.V4("192.168.1.1/24")
12+
val ip3 = IpInterface.V4("192.168.1.2/24")
13+
val ip4 = IpInterface.V4("192.168.1.1/16")
14+
15+
assertEquals(ip1, ip2, "Should be equal")
16+
assertNotEquals(ip1, ip3, "Different addresses should not be equal")
17+
assertNotEquals(ip1, ip4, "Different prefixes should not be equal")
18+
19+
assertEquals(ip1.hashCode(), ip2.hashCode(), "Equal objects must have equal hashCodes")
20+
assertNotEquals(ip1.hashCode(), ip3.hashCode(), "Should have different hashCodes")
21+
assertNotEquals(ip1.hashCode(), ip4.hashCode(), "Should have different hashCodes")
22+
}
23+
24+
@Test
25+
fun `IPv6 equals and hashCode`() {
26+
val ip1 = IpInterface.V6("2001:db8::1/64")
27+
val ip2 = IpInterface.V6("2001:db8::1/64")
28+
val ip3 = IpInterface.V6("2001:db8::2/64")
29+
val ip4 = IpInterface.V6("2001:db8::1/48")
30+
31+
assertEquals(ip1, ip2, "Should be equal")
32+
assertNotEquals(ip1, ip3, "Different addresses should not be equal")
33+
assertNotEquals(ip1, ip4, "Different prefixes should not be equal")
34+
35+
assertEquals(ip1.hashCode(), ip2.hashCode(), "Equal objects must have equal hashCodes")
36+
assertNotEquals(ip1.hashCode(), ip3.hashCode(), "Should have different hashCodes")
37+
assertNotEquals(ip1.hashCode(), ip4.hashCode(), "Should have different hashCodes")
38+
}
39+
40+
@Test
41+
fun `IPv4 and IPv6 are not equal`() {
42+
val ipv4 = IpInterface.V4("192.168.1.1/24")
43+
val ipv6 = IpInterface.V6("2001:db8::1/64")
44+
45+
assertNotEquals<IpInterface<*, *>>(ipv4, ipv6, "IPv4 and IPv6 should never be equal")
46+
}
47+
}

0 commit comments

Comments
 (0)