Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor EndpointInfo in Swift #3195

Merged
merged 3 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions swift/src/Ice/CommunicatorI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ class CommunicatorI: LocalObject<ICECommunicator>, Communicator {
self.initData = initData
do {
classGraphDepthMax = try initData.properties!.getIcePropertyAsInt("Ice.ClassGraphDepthMax")
precondition(classGraphDepthMax >= 1 && classGraphDepthMax <= 0x7FFF_FFFF, "Ice.ClassGraphDepthMax must be >= 0 and <= 0x7FFF_FFFF")
precondition(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to Swift format more often.

classGraphDepthMax >= 1 && classGraphDepthMax <= 0x7FFF_FFFF,
"Ice.ClassGraphDepthMax must be >= 0 and <= 0x7FFF_FFFF")
traceSlicing = try initData.properties!.getIcePropertyAsInt("Ice.Trace.Slicing") > 0
acceptClassCycles = try initData.properties!.getIcePropertyAsInt("Ice.AcceptClassCycles") > 0
} catch {
} catch {
fatalError("\(error)")
}

Expand Down
180 changes: 147 additions & 33 deletions swift/src/Ice/Endpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,191 @@

import Foundation

/// The user-level interface to an endpoint.
public protocol Endpoint: AnyObject, CustomStringConvertible {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved at the top of Endpoint.swift. Didn't change this protocol.

/// Return a string representation of the endpoint.
///
/// - returns: `String` - The string representation of the endpoint.
func toString() -> String

/// Returns the endpoint information.
///
/// - returns: `EndpointInfo?` - The endpoint information class.
func getInfo() -> EndpointInfo?
}

public typealias EndpointSeq = [Endpoint]

/// Base class providing access to the endpoint details.
public protocol EndpointInfo: AnyObject {
open class EndpointInfo {
/// The information of the underlying endpoint or null if there's no underlying endpoint.
var underlying: EndpointInfo? { get set }
public let underlying: EndpointInfo?
/// The timeout for the endpoint in milliseconds. 0 means non-blocking, -1 means no timeout.
var timeout: Int32 { get set }
public let timeout: Int32
/// Specifies whether or not compression should be used if available when using this endpoint.
var compress: Bool { get set }
public let compress: Bool

/// Returns the type of the endpoint.
///
/// - returns: `Int16` - The endpoint type.
func type() -> Int16
public func type() -> Int16 {
underlying?.type() ?? -1
}

/// Returns true if this endpoint is a datagram endpoint.
///
/// - returns: `Bool` - True for a datagram endpoint.
func datagram() -> Bool
public func datagram() -> Bool {
underlying?.datagram() ?? false
}

/// Returns true if this endpoint is a secure endpoint.
///
/// - returns: `Bool` - True for a secure endpoint.
func secure() -> Bool
}
public func secure() -> Bool {
underlying?.secure() ?? false
}

/// The user-level interface to an endpoint.
public protocol Endpoint: AnyObject, CustomStringConvertible {
/// Return a string representation of the endpoint.
///
/// - returns: `String` - The string representation of the endpoint.
func toString() -> String
public init(underlying: EndpointInfo) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logically "protected", but this is not available in Swift.

self.underlying = underlying
self.timeout = underlying.timeout
self.compress = underlying.compress
}

/// Returns the endpoint information.
///
/// - returns: `EndpointInfo?` - The endpoint information class.
func getInfo() -> EndpointInfo?
public init(timeout: Int32, compress: Bool) {
self.underlying = nil
self.timeout = timeout
self.compress = compress
}
}

/// Provides access to the address details of a IP endpoint.
public protocol IPEndpointInfo: EndpointInfo {
open class IPEndpointInfo: EndpointInfo {
/// The host or address configured with the endpoint.
var host: String { get set }
public let host: String
/// The port number.
var port: Int32 { get set }
public let port: Int32
/// The source IP address.
var sourceAddress: String { get set }
public let sourceAddress: String

public init(timeout: Int32, compress: Bool, host: String, port: Int32, sourceAddress: String) {
self.host = host
self.port = port
self.sourceAddress = sourceAddress
super.init(timeout: timeout, compress: compress)
}
}

/// Provides access to a TCP endpoint information.
public protocol TCPEndpointInfo: IPEndpointInfo {}
public final class TCPEndpointInfo: IPEndpointInfo {
private let _type: Int16
private let _secure: Bool

public override func type() -> Int16 {
_type
}

public override func secure() -> Bool {
_secure
}

internal init(
timeout: Int32, compress: Bool, host: String, port: Int32, sourceAddress: String, type: Int16, secure: Bool
) {
self._type = type
self._secure = secure
super.init(timeout: timeout, compress: compress, host: host, port: port, sourceAddress: sourceAddress)
}
}

/// Provides access to an UDP endpoint information.
public protocol UDPEndpointInfo: IPEndpointInfo {
public final class UDPEndpointInfo: IPEndpointInfo {
/// The multicast interface.
var mcastInterface: String { get set }
public let mcastInterface: String
/// The multicast time-to-live (or hops).
var mcastTtl: Int32 { get set }
public let mcastTtl: Int32

public override func type() -> Int16 {
UDPEndpointType
}

public override func datagram() -> Bool {
true
}

internal init(
compress: Bool, host: String, port: Int32, sourceAddress: String, mcastInterface: String, mcastTtl: Int32
) {
self.mcastInterface = mcastInterface
self.mcastTtl = mcastTtl
super.init(timeout: -1, compress: compress, host: host, port: port, sourceAddress: sourceAddress)
}
}

/// Provides access to a WebSocket endpoint information.
public protocol WSEndpointInfo: EndpointInfo {
public final class WSEndpointInfo: EndpointInfo {
/// The URI configured with the endpoint.
var resource: String { get set }
public let resource: String

internal init(underlying: EndpointInfo, resource: String) {
self.resource = resource
super.init(underlying: underlying)
}
}

/// Provides access to an IAP endpoint information.
public final class IAPEndpointInfo: EndpointInfo {
/// The accessory manufacturer or empty to not match against a manufacturer.
public let manufacturer: String
/// The accessory model number or empty to not match against a model number.
public let modelNumber: String
/// The accessory name or empty to not match against the accessory name.
public let name: String
/// The protocol supported by the accessory.
public let `protocol`: String

private let _type: Int16
private let _secure: Bool

public override func type() -> Int16 {
_type
}

public override func secure() -> Bool {
_secure
}

internal init(
timeout: Int32, compress: Bool, manufacturer: String, modelNumber: String, name: String, protocol: String,
type: Int16, secure: Bool
) {
self.manufacturer = manufacturer
self.modelNumber = modelNumber
self.name = name
self.`protocol` = `protocol`
self._type = type
self._secure = secure
super.init(timeout: timeout, compress: compress)
}
}

/// Provides access to the details of an opaque endpoint.
public protocol OpaqueEndpointInfo: EndpointInfo {
public final class OpaqueEndpointInfo: EndpointInfo {
/// The encoding version of the opaque endpoint (to decode or encode the rawBytes).
var rawEncoding: EncodingVersion { get set }
public let rawEncoding: EncodingVersion
/// The raw encoding of the opaque endpoint.
var rawBytes: ByteSeq { get set }
}
public let rawBytes: ByteSeq

public typealias EndpointSeq = [Endpoint]
private let _type: Int16

public override func type() -> Int16 {
_type
}

internal init(type: Int16, rawEncoding: EncodingVersion, rawBytes: ByteSeq) {
self.rawEncoding = rawEncoding
self.rawBytes = rawBytes
self._type = type
super.init(timeout: -1, compress: false)
}
}
138 changes: 0 additions & 138 deletions swift/src/Ice/EndpointI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,144 +35,6 @@ public func == (lhs: Endpoint?, rhs: Endpoint?) -> Bool {
}
}

// We implement EndpointInfo as a LocalObject that delegates to an ObjC/C++ object.
// The alternative - delegating to the Endpoint object - is not practical since the public API
// of Endpoint in C++ does not expose type, datagram or secure.
class EndpointInfoI: LocalObject<ICEEndpointInfo>, EndpointInfo {
var underlying: EndpointInfo?
var timeout: Int32
var compress: Bool

init(handle: ICEEndpointInfo, underlying: EndpointInfo?, timeout: Int32, compress: Bool) {
self.underlying = underlying
self.timeout = timeout
self.compress = compress
super.init(handle: handle)
}

func type() -> Int16 {
return handle.getType()
}

func datagram() -> Bool {
return handle.getDatagram()
}

func secure() -> Bool {
return handle.getSecure()
}
}

// This class is logically abstract and only derived classes should be created.
class IPEndpointInfoI: EndpointInfoI, IPEndpointInfo {
var host: String
var port: Int32
var sourceAddress: String

init(
handle: ICEEndpointInfo,
underlying: EndpointInfo?,
timeout: Int32,
compress: Bool,
host: String,
port: Int32,
sourceAddress: String
) {
self.host = host
self.port = port
self.sourceAddress = sourceAddress
super.init(handle: handle, underlying: underlying, timeout: timeout, compress: compress)
}
}

class TCPEndpointInfoI: IPEndpointInfoI, TCPEndpointInfo {}

class UDPEndpointInfoI: IPEndpointInfoI, UDPEndpointInfo {
var mcastInterface: String
var mcastTtl: Int32

init(
handle: ICEEndpointInfo,
underlying: EndpointInfo?,
timeout: Int32,
compress: Bool,
host: String,
port: Int32,
sourceAddress: String,
mcastInterface: String,
mcastTtl: Int32
) {
self.mcastInterface = mcastInterface
self.mcastTtl = mcastTtl
super.init(
handle: handle,
underlying: underlying,
timeout: timeout,
compress: compress,
host: host,
port: port,
sourceAddress: sourceAddress)
}
}

class WSEndpointInfoI: EndpointInfoI, WSEndpointInfo {
var resource: String

init(
handle: ICEEndpointInfo, underlying: EndpointInfo?, timeout: Int32, compress: Bool,
resource: String
) {
self.resource = resource
super.init(handle: handle, underlying: underlying, timeout: timeout, compress: compress)
}
}

class OpaqueEndpointInfoI: EndpointInfoI, OpaqueEndpointInfo {
var rawEncoding: EncodingVersion
var rawBytes: ByteSeq

init(
handle: ICEEndpointInfo,
underlying: EndpointInfo?,
timeout: Int32,
compress: Bool,
rawEncoding: EncodingVersion,
rawBytes: ByteSeq
) {
self.rawEncoding = rawEncoding
self.rawBytes = rawBytes
super.init(handle: handle, underlying: underlying, timeout: timeout, compress: compress)
}
}

//
// IceSSL
//
class SSLEndpointInfoI: EndpointInfoI, SSLEndpointInfo {}

#if os(iOS) || os(watchOS) || os(tvOS)

// IceIAP (iOS only)
class IAPEndpointInfoI: EndpointInfoI, IAPEndpointInfo {
var manufacturer: String
var modelNumber: String
var name: String
var `protocol`: String

init(
handle: ICEEndpointInfo, underlying: EndpointInfo?, timeout: Int32, compress: Bool,
manufacturer: String, modelNumber: String, name: String, protocol: String
) {
self.manufacturer = manufacturer
self.modelNumber = modelNumber
self.name = name
self.protocol = `protocol`
super.init(handle: handle, underlying: underlying, timeout: timeout, compress: compress)
}
}

#endif

//
// Internal helpers to convert from ObjC to Swift objects
//
Expand Down
Loading