mirror of
https://github.com/apple/swift-nio.git
synced 2026-05-20 20:30:36 +00:00
abe4f1bcb6
Motivation: Public static lets can serve a bunch of roles, but one of them is to store simple constants: integers, and other trivial types, for example. This is a nice pattern and for internal and private static lets it works well, but for public ones it produces some inefficient code. In particular, it has two downsides. First, it allocates storage for that value. We don't actually need to allocate a few hundred extra megabytes for the various integers we want to store. Secondly, it forces calling code to access the address and call the dispatch_once code in order to get hold of the value. For trivial types we don't need that cost: they can just know what the value is directly. Inlinable computed vars avoid all of these costs: they have no size overhead for storage, and they are visible to all clients so their values can be directly assembled. While I'm here, I added a bunch of other inlinable annotations for a few trivial data types I stumbled onto. Modifications: - Added loads of inlinables. Like, loads. - Swapped many static lets to static vars. Result: Better codegen, smaller memory footprints, more attributes.
145 lines
4.0 KiB
Swift
145 lines
4.0 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the SwiftNIO open source project
|
|
//
|
|
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
|
|
// Licensed under Apache License v2.0
|
|
//
|
|
// See LICENSE.txt for license information
|
|
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import NIOCore
|
|
|
|
/// An operation code for a websocket frame.
|
|
public struct WebSocketOpcode: Sendable {
|
|
@usableFromInline
|
|
let networkRepresentation: UInt8
|
|
|
|
@inlinable
|
|
public static var continuation: WebSocketOpcode {
|
|
WebSocketOpcode(rawValue: 0x0)
|
|
}
|
|
|
|
@inlinable
|
|
public static var text: WebSocketOpcode {
|
|
WebSocketOpcode(rawValue: 0x1)
|
|
}
|
|
|
|
@inlinable
|
|
public static var binary: WebSocketOpcode {
|
|
WebSocketOpcode(rawValue: 0x2)
|
|
}
|
|
|
|
@inlinable
|
|
public static var connectionClose: WebSocketOpcode {
|
|
WebSocketOpcode(rawValue: 0x8)
|
|
}
|
|
|
|
@inlinable
|
|
public static var ping: WebSocketOpcode {
|
|
WebSocketOpcode(rawValue: 0x9)
|
|
}
|
|
|
|
@inlinable
|
|
public static var pong: WebSocketOpcode {
|
|
WebSocketOpcode(rawValue: 0xA)
|
|
}
|
|
|
|
/// Create an opcode from the encoded representation.
|
|
///
|
|
/// - Parameters
|
|
/// - encoded: The encoded representation of the opcode as an 8-bit integer.
|
|
/// Must be no more than 4 bits large.
|
|
@inlinable
|
|
public init?(encodedWebSocketOpcode encoded: UInt8) {
|
|
guard encoded < 0x10 else {
|
|
return nil
|
|
}
|
|
|
|
self.networkRepresentation = encoded
|
|
}
|
|
|
|
/// Create an opcode directly with no validation.
|
|
///
|
|
/// Used only to create the static vars on this structure.
|
|
@inlinable
|
|
init(rawValue: UInt8) {
|
|
self.networkRepresentation = rawValue
|
|
}
|
|
|
|
/// Whether the opcode is in the control range: that is, if the
|
|
/// high bit of the opcode nibble is `1`.
|
|
@inlinable
|
|
public var isControlOpcode: Bool {
|
|
self.networkRepresentation & 0x8 == 0x8
|
|
}
|
|
}
|
|
|
|
extension WebSocketOpcode: Equatable {}
|
|
|
|
extension WebSocketOpcode: Hashable {}
|
|
|
|
extension WebSocketOpcode: CaseIterable {
|
|
@inlinable
|
|
public static var allCases: [WebSocketOpcode] {
|
|
get { (0..<0x10).map { WebSocketOpcode(rawValue: $0) } }
|
|
|
|
@available(*, deprecated)
|
|
set {}
|
|
}
|
|
}
|
|
|
|
extension WebSocketOpcode: CustomStringConvertible {
|
|
public var description: String {
|
|
switch self {
|
|
case .continuation:
|
|
return "WebSocketOpcode.continuation"
|
|
case .text:
|
|
return "WebSocketOpcode.text"
|
|
case .binary:
|
|
return "WebSocketOpcode.binary"
|
|
case .connectionClose:
|
|
return "WebSocketOpcode.connectionClose"
|
|
case .ping:
|
|
return "WebSocketOpcode.ping"
|
|
case .pong:
|
|
return "WebSocketOpcode.pong"
|
|
case let x where x.isControlOpcode:
|
|
return "WebSocketOpcode.unknownControl(\(x.networkRepresentation))"
|
|
case let x:
|
|
return "WebSocketOpcode.unknownNonControl(\(x.networkRepresentation))"
|
|
}
|
|
}
|
|
}
|
|
|
|
extension UInt8 {
|
|
/// Create a UInt8 corresponding to a given `WebSocketOpcode`.
|
|
///
|
|
/// This places the opcode in the four least-significant bits, in
|
|
/// a form suitable for sending on the wire.
|
|
///
|
|
/// - Parameters:
|
|
/// - opcode: The `WebSocketOpcode`.
|
|
@inlinable
|
|
public init(webSocketOpcode opcode: WebSocketOpcode) {
|
|
precondition(opcode.networkRepresentation < 0x10)
|
|
self = opcode.networkRepresentation
|
|
}
|
|
}
|
|
|
|
extension Int {
|
|
/// Create a UInt8 corresponding to the integer value for a given `WebSocketOpcode`.
|
|
///
|
|
/// - Parameters:
|
|
/// - opcode: The `WebSocketOpcode`.
|
|
@inlinable
|
|
public init(webSocketOpcode opcode: WebSocketOpcode) {
|
|
precondition(opcode.networkRepresentation < 0x10)
|
|
self = Int(opcode.networkRepresentation)
|
|
}
|
|
}
|