/*
* 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.
*/
package std.net
const SOCK_LEN_MAX: Int64 = 120
/**
* Socket domain values.
*/
@When[os != "Windows" && os != "macOS" && os != "iOS"]
public struct SocketDomain <: Equatable<SocketDomain> & ToString & Hashable {
let val: Int32
public static let IPV4: SocketDomain = SocketDomain(AF_INET)
public static let IPV6: SocketDomain = SocketDomain(AF_INET6)
public static let UNIX: SocketDomain = SocketDomain(AF_UNIX)
public static let NETLINK: SocketDomain = SocketDomain(AF_NETLINK)
public static let PACKET: SocketDomain = SocketDomain(AF_PACKET)
public init(domain: Int32) {
this.val = domain
}
private init(domain: Int16) {
this(Int32(domain))
}
public operator func ==(r: SocketDomain): Bool {
return this.val == r.val
}
public operator func !=(r: SocketDomain): Bool {
return !(this == r)
}
public func toString(): String {
return match {
case val == Int32(AF_INET) => "IPv4"
case val == Int32(AF_INET6) => "IPv6"
case val == Int32(AF_UNIX) => "unix"
case val == Int32(AF_NETLINK) => "netlink"
case val == Int32(AF_PACKET) => "packet"
case _ => "Domain(${val})"
}
}
public func hashCode(): Int64 {
return Int64(val)
}
}
@When[os == "Windows" || os == "macOS" || os == "iOS"]
public struct SocketDomain <: Equatable<SocketDomain> & ToString & Hashable {
let val: Int32
public static let IPV4: SocketDomain = SocketDomain(AF_INET)
public static let IPV6: SocketDomain = SocketDomain(AF_INET6)
public static let UNIX: SocketDomain = SocketDomain(AF_UNIX)
private init(domain: Int16) {
this(Int32(domain))
}
public init(domain: Int32) {
this.val = domain
}
public operator func ==(r: SocketDomain): Bool {
return this.val == r.val
}
public operator func !=(r: SocketDomain): Bool {
return !(this == r)
}
public func hashCode(): Int64 {
return Int64(val)
}
public func toString(): String {
return match {
case val == Int32(AF_INET) => "IPv4"
case val == Int32(AF_INET6) => "IPv6"
case val == Int32(AF_UNIX) => "unix"
case _ => "Domain(${val})"
}
}
}
/**
* Socket type values.
*/
public struct SocketType <: Equatable<SocketType> & ToString & Hashable {
let val: Int32
public static let STREAM: SocketType = SocketType(SOCKET_STREAM)
public static let DATAGRAM: SocketType = SocketType(SOCKET_DGRAM)
public static let RAW: SocketType = SocketType(SOCKET_RAW)
public static let SEQPACKET: SocketType = SocketType(SOCKET_SEQPACKET)
public init(`type`: Int32) {
this.val = `type`
}
public operator func ==(r: SocketType): Bool {
return this.val == r.val
}
public operator func !=(r: SocketType): Bool {
return !(this == r)
}
public func toString(): String {
return match {
case val == SOCKET_STREAM => "STREAM"
case val == SOCKET_DGRAM => "DATAGRAM"
case val == SOCKET_RAW => "RAW"
case val == SOCKET_SEQPACKET => "SEQPACKET"
case _ => "Type(${val})"
}
}
public func hashCode(): Int64 {
return Int64(val)
}
}
/**
* Socket protocol values.
*/
public struct ProtocolType <: Equatable<ProtocolType> & ToString & Hashable {
let val: Int32
public static let Unspecified: ProtocolType = ProtocolType(0)
public static let IPV4: ProtocolType = ProtocolType(IPPROTO_IPV4)
public static let IPV6: ProtocolType = ProtocolType(IPPROTO_IPV6)
public static let ICMP: ProtocolType = ProtocolType(IPPROTO_ICMP)
public static let TCP: ProtocolType = ProtocolType(IPPROTO_TCP)
public static let UDP: ProtocolType = ProtocolType(IPPROTO_UDP)
public static let RAW: ProtocolType = ProtocolType(IPPROTO_RAW)
public init(protocol: Int32) {
this.val = protocol
}
public operator func ==(r: ProtocolType): Bool {
return this.val == r.val
}
public operator func !=(r: ProtocolType): Bool {
return !(this == r)
}
public func toString(): String {
return match {
case val == 0 => "Unspecified"
case val == IPPROTO_IPV4 => "IPv4"
case val == IPPROTO_IPV6 => "IPv6"
case val == IPPROTO_ICMP => "ICMP"
case val == IPPROTO_TCP => "TCP"
case val == IPPROTO_UDP => "UDP"
case val == IPPROTO_RAW => "RAW"
case _ => "Protocol(${val})"
}
}
public func hashCode(): Int64 {
return Int64(val)
}
}
/**
* Socket option level values.
*/
public struct OptionLevel {
public static const IP: Int32 = IPPROTO_IP
public static const TCP: Int32 = IPPROTO_TCP
public static const UDP: Int32 = IPPROTO_UDP
public static const ICMP: Int32 = IPPROTO_ICMP
public static const RAW: Int32 = IPPROTO_RAW
public static const SOCKET: Int32 = SOL_SOCKET
}
/**
* Socket optoin name values.
*/
public struct OptionName {
// IPOption
public static const IP_HDRINCL: Int32 = SOCK_IP_HDRINCL
public static const IP_TOS: Int32 = SOCK_IP_TOS
public static const IP_TTL: Int32 = SOCK_IP_TTL
// TCPOption
public static const TCP_KEEPCNT: Int32 = SOCK_TCP_KEEPCNT
public static const TCP_KEEPIDLE: Int32 = SOCK_TCP_KEEPIDLE
public static const TCP_KEEPINTVL: Int32 = SOCK_TCP_KEEPINTVL
public static const TCP_NODELAY: Int32 = SOCK_TCP_NODELAY
// SOCKETOption
public static const SO_DEBUG: Int32 = SOCK_DEBUG
public static const SO_ACCEPTCONN: Int32 = SOCK_ACCEPTCONN
public static const SO_REUSEADDR: Int32 = SOCK_REUSEADDR
public static const SO_KEEPALIVE: Int32 = SOCK_KEEPALIVE
public static const SO_DONTROUTE: Int32 = SOCK_DONTROUTE
public static const SO_BROADCAST: Int32 = SOCK_BROADCAST
public static const SO_LINGER: Int32 = SOCK_LINGER
public static const SO_OOBINLINE: Int32 = SOCK_OOBINLINE
public static const SO_SNDBUF: Int32 = SOCK_SNDBUF
public static const SO_RCVBUF: Int32 = SOCK_RCVBUF
public static const SO_SNDTIMEO: Int32 = SOCK_SNDTIMEO
public static const SO_RCVTIMEO: Int32 = SOCK_RCVTIMEO
public static const SO_ERROR: Int32 = SOCK_ERROR
}
/**
* This class defines the address for RawSocket.
*/
public struct RawAddress {
let addr_: Array<Byte>
/* Get the array of RawAddress */
public prop addr: Array<Byte> {
get() {
this.addr_
}
}
/**
* Initialize an address with a byte array.
* The byte array needs to be memory aligned with the C struct, such as SockAddrIn, SockAddrUn.
*
* @param addr The byte sequence corresponding to socket address.
*/
public init(addr: Array<Byte>) {
this.addr_ = addr
}
}
func getTimeout(timeout: Option<Duration>): Int64 {
match (timeout) {
case Some(v) =>
if (v < Duration.Zero) {
throw IllegalArgumentException("Timeout should not be negative.")
}
if (v > MAX_TIMEOUT_DURATION) {
return MAX_TIMEOUT_NS
}
return v.toNanoseconds()
case None => return -1
}
}