/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
// The Cangjie API is in Beta. For details on its capabilities and limitations, please refer to the README file.
/**
* @file The file declares several util functions.
*/
package std.net
const OS_WINDOWS = "windows"
const OS_MACOS = "macOS"
const OS_OTHERS = "others"
const MAX_TIMEOUT_NS: Int64 = 0x7FFF_FFFF_FFFF_FFFF
let MAX_TIMEOUT_DURATION: Duration = Duration.nanosecond * MAX_TIMEOUT_NS
@When[os != "Windows" && os != "macOS" && os != "iOS"]
const OS = OS_OTHERS
@When[os == "macOS" || os == "iOS"]
const OS = OS_MACOS
@When[os == "Windows"]
const OS = OS_WINDOWS
extend Int64 {
func clampIn(min!: Int64, max!: Int64): Int64 {
if (this < min) {
return min
}
if (this > max) {
return max
}
return this
}
func toUInt32In(min!: UInt32, max!: UInt32 = UInt32.Max): UInt32 {
let clamped = clampIn(min: Int64(min), max: Int64(max))
UInt32(clamped)
}
}
extend UInt64 {
func atLeast(n: UInt64): UInt64 {
if (this < n) {
return n
}
return this
}
}
func unwrapOption<T>(opt: ??T): ?T {
return opt ?? None
}
func getOrFail<T>(e: () -> Exception): (?T) -> T {
return {it: ?T => it ?? throw e()}
}
func formatError(errnum: Int32): String {
unsafe {
let result = CJ_SOCKET_GetErrMessage(errnum)
if (result.isNull() || result.isEmpty()) {
return "Unknown error: ${errnum}"
}
return try {
result.toString()
} finally {
LibC.free(result)
}
}
}
func throwIfIPv4ZeroOnWindows(socketAddress: SocketAddress): Unit {
if (OS == OS_WINDOWS) {
let ipsa = (socketAddress as IPSocketAddress) ?? return;
if (ipsa.address.isUnspecified()) {
throw SocketException("Impossible to communicate with 0.0.0.0 on windows. Try to use concrete address.")
}
}
}
func zeroMemory(buffer: CPointer<UInt8>, size: Int64) {
for (i in 0..size) {
unsafe { buffer.write(i, 0) }
}
}
func resolveHelper(address: String): IPAddress {
let ips = IPAddress.resolve(address)
if (ips.size > 0) {
return ips[0]
}
throw SocketException("Failed to resolve address ${address}.")
}