Skip to content

Instantly share code, notes, and snippets.

@saagarjha
Last active February 12, 2018 22:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saagarjha/7320d04b4cde789e65ca17ead5694e2b to your computer and use it in GitHub Desktop.
Save saagarjha/7320d04b4cde789e65ca17ead5694e2b to your computer and use it in GitHub Desktop.
(Broken) Swifty wrapper around POSIX sockets
import Foundation
protocol SockAddr { }
extension sockaddr_in: SockAddr { }
extension sockaddr_in6: SockAddr { }
enum SocketAddress: CustomDebugStringConvertible {
case ipv4(sockaddr_in)
case ipv6(sockaddr_in6)
init(address: sockaddr_in) {
self = .ipv4(address)
}
init(address: sockaddr_in6) {
self = .ipv6(address)
}
init(address: UnsafePointer<sockaddr>) {
switch Int32(address.pointee.sa_family) {
case AF_INET:
self = .ipv4(UnsafeRawPointer(address).assumingMemoryBound(to: sockaddr_in.self).pointee)
case AF_INET6:
self = .ipv6(UnsafeRawPointer(address).assumingMemoryBound(to: sockaddr_in6.self).pointee)
default:
preconditionFailure("Invalid address type")
}
}
var associatedValue: UnsafeRawPointer {
switch self {
case .ipv4(var address):
return UnsafeRawPointer(UnsafeMutablePointer(&address))
case .ipv6(var address):
return UnsafeRawPointer(UnsafeMutablePointer(&address))
}
}
var socketAddress: sockaddr {
return associatedValue.assumingMemoryBound(to: sockaddr.self).pointee
}
var size: socklen_t {
switch self {
case .ipv4(_):
return socklen_t(MemoryLayout<sockaddr_in>.size)
case .ipv6(_):
return socklen_t(MemoryLayout<sockaddr_in6>.size)
}
}
public var debugDescription: String {
var version: String
var addr: UnsafeRawPointer
switch self {
case .ipv4(var address):
version = "IPv4"
addr = UnsafeRawPointer(UnsafeMutablePointer(&address.sin_addr))
case .ipv6(var address):
version = "IPv6"
addr = UnsafeRawPointer(UnsafeMutablePointer(&address.sin6_addr))
}
var buffer = [CChar](repeating: 0, count: Int(INET6_ADDRSTRLEN))
inet_ntop(self.version, addr, &buffer, socklen_t(buffer.count))
return "\(version) \(String(cString: buffer))"
}
var version: Int32 {
switch self {
case .ipv4(_):
return AF_INET
case .ipv6(_):
return AF_INET6
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment