//===--- Utils.swift - Some bridging utilities ----------------------------===// // // 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 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// @_exported import BasicBridging //===----------------------------------------------------------------------===// // Bridging Utilities //===----------------------------------------------------------------------===// extension BridgedStringRef { public var string: String { let buffer = UnsafeBufferPointer(start: data, count: Int(length)) return String(decoding: buffer, as: UTF8.self) } public func takeString() -> String { let str = string freeBridgedStringRef(self) return str } } extension String { public func withBridgedStringRef(_ c: (BridgedStringRef) -> T) -> T { var str = self return str.withUTF8 { buffer in return c(BridgedStringRef(data: buffer.baseAddress, length: buffer.count)) } } } extension Array { public func withBridgedArrayRef(_ c: (BridgedArrayRef) -> T) -> T { return withUnsafeBytes { buf in return c(BridgedArrayRef(data: buf.baseAddress!, numElements: count)) } } } public typealias SwiftObject = UnsafeMutablePointer extension UnsafeMutablePointer where Pointee == BridgedSwiftObject { public init(_ object: T) { let ptr = Unmanaged.passUnretained(object).toOpaque() self = ptr.bindMemory(to: BridgedSwiftObject.self, capacity: 1) } public func getAs(_ objectType: T.Type) -> T { return Unmanaged.fromOpaque(self).takeUnretainedValue() } } extension Optional where Wrapped == UnsafeMutablePointer { public func getAs(_ objectType: T.Type) -> T? { if let pointer = self { return Unmanaged.fromOpaque(pointer).takeUnretainedValue() } return nil } } extension BridgedArrayRef { public func withElements(ofType ty: T.Type, _ c: (UnsafeBufferPointer) -> R) -> R { let start = data?.bindMemory(to: ty, capacity: numElements); let buffer = UnsafeBufferPointer(start: start, count: numElements); return c(buffer) } }