Repository: ktorio/ktor
File: ktor-network/nonJvm/src/io/ktor/network/sockets/SocketAddress.nonJvm.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.network.sockets

public actual sealed class SocketAddress

public actual class InetSocketAddress actual constructor(
    public actual val hostname: String,
    public actual val port: Int
) : SocketAddress() {
    public actual fun address(): ByteArray? {
        val maybeIPv4 = hostname.contains('.')
        val maybeIPv6 = hostname.contains(':')

        if (maybeIPv4) {
            try {
                val octets = hostname.split('.', limit = 4).map { it.toInt().toByte() }
                return List(4) { octets.getOrElse(it) { 0 } }.toByteArray()
            } catch (_: Throwable) {}
        }

        if (maybeIPv6) {
            try {
                val groups = hostname.split(':', limit = 8)
                val emptyGroups = 8 - groups.count { it.isNotEmpty() }

                val bytes = groups.flatMap {
                    if (it.isEmpty()) {
                        List(emptyGroups * 2) { 0 }
                    } else {
                        val int = it.toInt(16)
                        listOf((int shr 8).toByte(), int.toByte())
                    }
                }
                return List(16) { bytes.getOrElse(it) { 0 } }.toByteArray()
            } catch (_: Throwable) {}
        }

Review comment (suggestion):
For native targets we have internal extension-function `fun SocketAddress.resolve()` that could be used in the following way:
```kotlin
val resolvedAddress = this.resolve().firstOrNull() ?: return null

return when (resolvedAddress) {
    is NativeIPv4SocketAddress -> ipv4ToBytes(resolvedAddress.ipString)
    is NativeIPv6SocketAddress -> ipv6ToBytes(resolvedAddress.ipString)
    else -> null
}
```
(Functions `ipv4ToBytes` and `ipv6ToBytes` needs to be implemented.)

For Kotlin/JS, Kotlin/Wasm I'd propose returning `null` unconditionally and mention this behavior in the KDoc comment.

Code after:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.network.sockets

public actual sealed class SocketAddress

public actual class InetSocketAddress actual constructor(
    public actual val hostname: String,
    public actual val port: Int
) : SocketAddress() {
    public actual fun resolveAddress(): ByteArray? {
        return platformResolveAddress()
    }

    /**
     * Create a copy of [InetSocketAddress].
     *
     * Note that this may trigger a name service reverse lookup.
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.copy)
     */
    public actual fun copy(hostname: String, port: Int): InetSocketAddress {
        return InetSocketAddress(hostname, port)
    }

    /**
     * The hostname of the socket address.
     *
     * Note that this may trigger a name service reverse lookup.
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.network.sockets.InetSocketAddress.component1)
     */
    public actual operator fun component1(): String {
        return hostname
    }

    /**