1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//
#if FOUNDATION_FRAMEWORK
internal import _ForSwiftFoundation
#if canImport(Darwin.uuid)
// Needed this for backward compatibility even though we don't use it.
import Darwin.uuid
#endif
@available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *)
extension UUID : ReferenceConvertible {
public typealias ReferenceType = NSUUID
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSUUID {
return __NSConcreteUUID(value: self)
}
public static func _forceBridgeFromObjectiveC(_ x: NSUUID, result: inout UUID?) {
if !_conditionallyBridgeFromObjectiveC(x, result: &result) {
fatalError("Unable to bridge \(_ObjectiveCType.self) to \(self)")
}
}
public static func _conditionallyBridgeFromObjectiveC(_ input: NSUUID, result: inout UUID?) -> Bool {
// Is this NSUUID already backed by a UUID?
guard let swiftInput = input as? __NSConcreteUUID else {
// Fallback to using bytes
var bytes = uuid_t(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
input.getBytes(&bytes)
result = UUID(uuid: bytes)
return true
}
result = swiftInput._storage
return true
}
@_effects(readonly)
public static func _unconditionallyBridgeFromObjectiveC(_ source: NSUUID?) -> UUID {
var result: UUID?
_forceBridgeFromObjectiveC(source!, result: &result)
return result!
}
}
@available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *)
extension NSUUID : _HasCustomAnyHashableRepresentation {
// Must be @nonobjc to avoid infinite recursion during bridging.
@nonobjc
public func _toCustomAnyHashable() -> AnyHashable? {
return AnyHashable(self as UUID)
}
}
@objc(__NSConcreteUUID)
internal class __NSConcreteUUID : _NSUUIDBridge, @unchecked Sendable {
final var _storage: UUID
fileprivate init(value: Foundation.UUID) {
_storage = value
super.init()
}
override public init() {
_storage = Foundation.UUID()
super.init()
}
override static var supportsSecureCoding: Bool { true }
required init?(coder: NSCoder) {
guard coder.allowsKeyedCoding else {
coder.failWithError(CocoaError(CocoaError.coderReadCorrupt, userInfo: [NSDebugDescriptionErrorKey : "Cannot be decoded without keyed coding"]))
return nil
}
var decodedByteLength = 0
let bytes = coder.decodeBytes(forKey: "NS.uuidbytes", returnedLength: &decodedByteLength)
guard let bytes else {
if NSUUID._compatibilityBehavior {
let empty = uuid_t(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
_storage = Foundation.UUID(uuid: empty)
super.init()
return
} else {
coder.failWithError(CocoaError(CocoaError.coderValueNotFound, userInfo: [NSDebugDescriptionErrorKey : "UUID bytes not found in archive"]))
return nil
}
}
guard decodedByteLength == MemoryLayout<uuid_t>.size else {
if NSUUID._compatibilityBehavior {
let empty = uuid_t(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
_storage = Foundation.UUID(uuid: empty)
super.init()
return
} else {
coder.failWithError(CocoaError(CocoaError.coderReadCorrupt, userInfo: [NSDebugDescriptionErrorKey : "UUID bytes were not the expected length"]))
return nil
}
}
let cUUID = bytes.withMemoryRebound(to: uuid_t.self, capacity: 1, { $0.pointee })
_storage = Foundation.UUID(uuid: cUUID)
super.init()
}
override func encode(with coder: NSCoder) {
_storage.withUUIDBytes { buffer in
coder.encodeBytes(buffer.baseAddress, length: buffer.count, forKey: "NS.uuidbytes")
}
}
override public init?(uuidString: String) {
guard let swiftUUID = Foundation.UUID(uuidString: uuidString) else {
if NSUUID._compatibilityBehavior {
let empty = uuid_t(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
_storage = Foundation.UUID(uuid: empty)
super.init()
return
} else {
return nil
}
}
_storage = swiftUUID
super.init()
}
override public init(uuidBytes: UnsafePointer<UInt8>?) {
let cUUID = uuidBytes?.withMemoryRebound(to: uuid_t.self, capacity: 1, {
$0.pointee
}) ?? (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
_storage = Foundation.UUID(uuid: cUUID)
super.init()
}
override open func getBytes(_ bytes: UnsafeMutablePointer<UInt8>) {
_storage.withUUIDBytes { buffer in
bytes.initialize(from: buffer.baseAddress!, count: buffer.count)
}
}
override open var uuidString: String {
@objc(UUIDString) get {
_storage.uuidString
}
}
override var description: String {
self.uuidString
}
override var debugDescription: String {
withUnsafePointer(to: self) { ptr in
"<\(Self.self) \(ptr.debugDescription)> \(self.uuidString)"
}
}
override var classForCoder: AnyClass {
return NSUUID.self
}
}
#endif
|