Skip to content

Commit

Permalink
Refactor ConnectionInfo in Swift (#3207)
Browse files Browse the repository at this point in the history
  • Loading branch information
bernardnormier authored Dec 2, 2024
1 parent 70b3704 commit b7c2807
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 366 deletions.
163 changes: 136 additions & 27 deletions swift/src/Ice/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,6 @@ extension OutputStream {
/// A collection of HTTP headers.
public typealias HeaderDict = [String: String]

/// Base class providing access to the connection details.
public protocol ConnectionInfo: AnyObject {
/// The information of the underlying transport or null if there's no underlying transport.
var underlying: ConnectionInfo? { get set }
/// Whether or not the connection is an incoming or outgoing connection.
var incoming: Bool { get set }
/// The name of the adapter associated with the connection.
var adapterName: String { get set }
/// The connection id.
var connectionId: String { get set }
}

/// An application can implement this interface to receive notifications when a connection closes.
///
/// This method is called by the connection when the connection is closed. If the callback needs more information
Expand Down Expand Up @@ -169,40 +157,161 @@ public protocol Connection: AnyObject, CustomStringConvertible {
func throwException() throws
}

/// Base class providing access to the connection details.
open class ConnectionInfo {
/// The information of the underlying transport or null if there's no underlying transport.
public let underlying: ConnectionInfo?

/// Whether or not the connection is an incoming or outgoing connection.
public let incoming: Bool

/// The name of the adapter associated with the connection.
public let adapterName: String

/// The connection id.
public let connectionId: String

public init(underlying: ConnectionInfo) {
self.underlying = underlying
self.incoming = underlying.incoming
self.adapterName = underlying.adapterName
self.connectionId = underlying.connectionId
}

public init(incoming: Bool, adapterName: String, connectionId: String) {
self.underlying = nil
self.incoming = incoming
self.adapterName = adapterName
self.connectionId = connectionId
}
}

/// Provides access to the connection details of an IP connection
public protocol IPConnectionInfo: ConnectionInfo {
open class IPConnectionInfo: ConnectionInfo {
/// The local address.
var localAddress: String { get set }
public let localAddress: String

/// The local port.
var localPort: Int32 { get set }
public let localPort: Int32

/// The remote address.
var remoteAddress: String { get set }
public let remoteAddress: String

/// The remote port.
var remotePort: Int32 { get set }
public let remotePort: Int32

public init(
incoming: Bool, adapterName: String, connectionId: String, localAddress: String, localPort: Int32,
remoteAddress: String, remotePort: Int32
) {
self.localAddress = localAddress
self.localPort = localPort
self.remoteAddress = remoteAddress
self.remotePort = remotePort
super.init(incoming: incoming, adapterName: adapterName, connectionId: connectionId)
}
}

/// Provides access to the connection details of a TCP connection
public protocol TCPConnectionInfo: IPConnectionInfo {
public final class TCPConnectionInfo: IPConnectionInfo {
/// The connection buffer receive size.
var rcvSize: Int32 { get set }
public let rcvSize: Int32

/// The connection buffer send size.
var sndSize: Int32 { get set }
public let sndSize: Int32

internal init(
incoming: Bool, adapterName: String, connectionId: String, localAddress: String, localPort: Int32,
remoteAddress: String, remotePort: Int32, rcvSize: Int32, sndSize: Int32
) {
self.rcvSize = rcvSize
self.sndSize = sndSize
super.init(
incoming: incoming, adapterName: adapterName, connectionId: connectionId, localAddress: localAddress,
localPort: localPort, remoteAddress: remoteAddress, remotePort: remotePort)
}
}

/// Provides access to the connection details of an SSL connection
public final class SSLConnectionInfo: ConnectionInfo {
/// The certificate chain.
public let peerCertificate: SecCertificate?

internal init(underlying: ConnectionInfo, peerCertificate: SecCertificate?) {
self.peerCertificate = peerCertificate
super.init(underlying: underlying)
}
}

/// Provides access to the connection details of a UDP connection
public protocol UDPConnectionInfo: IPConnectionInfo {
public final class UDPConnectionInfo: IPConnectionInfo {
/// The multicast address.
var mcastAddress: String { get set }
public let mcastAddress: String

/// The multicast port.
var mcastPort: Int32 { get set }
public let mcastPort: Int32

/// The connection buffer receive size.
var rcvSize: Int32 { get set }
public let rcvSize: Int32

/// The connection buffer send size.
var sndSize: Int32 { get set }
public let sndSize: Int32

internal init(
incoming: Bool, adapterName: String, connectionId: String, localAddress: String, localPort: Int32,
remoteAddress: String, remotePort: Int32, mcastAddress: String, mcastPort: Int32, rcvSize: Int32, sndSize: Int32
) {
self.mcastAddress = mcastAddress
self.mcastPort = mcastPort
self.rcvSize = rcvSize
self.sndSize = sndSize
super.init(
incoming: incoming, adapterName: adapterName, connectionId: connectionId, localAddress: localAddress,
localPort: localPort, remoteAddress: remoteAddress, remotePort: remotePort)
}
}

/// Provides access to the connection details of a WebSocket connection
public protocol WSConnectionInfo: ConnectionInfo {
public final class WSConnectionInfo: ConnectionInfo {
/// The headers from the HTTP upgrade request.
var headers: HeaderDict { get set }
public let headers: HeaderDict

internal init(underlying: ConnectionInfo, headers: HeaderDict) {
self.headers = headers
super.init(underlying: underlying)
}
}

/// Provides access to the connection details of an IAP connection.
public final class IAPConnectionInfo: ConnectionInfo {
/// The accessory name.
public let name: String

/// The accessory manufacturer.
public let manufacturer: String

/// The accessory model number.
public let modelNumber: String

/// The accessory firmware revision.
public let firmwareRevision: String

/// The accessory hardware revision.
public let hardwareRevision: String

/// The protocol used by the accessory.
public let `protocol`: String

internal init(
incoming: Bool, adapterName: String, connectionId: String, name: String, manufacturer: String,
modelNumber: String, firmwareRevision: String, hardwareRevision: String, `protocol`: String
) {
self.name = name
self.manufacturer = manufacturer
self.modelNumber = modelNumber
self.firmwareRevision = firmwareRevision
self.hardwareRevision = hardwareRevision
self.protocol = `protocol`
super.init(incoming: incoming, adapterName: adapterName, connectionId: connectionId)
}
}
Loading

0 comments on commit b7c2807

Please sign in to comment.