diff --git a/Support/Sources/WindowsRuntime/IReferenceProjection+Primitive.swift b/Support/Sources/WindowsRuntime/IReferenceProjection+Primitive.swift index d8317c61..9af33524 100644 --- a/Support/Sources/WindowsRuntime/IReferenceProjection+Primitive.swift +++ b/Support/Sources/WindowsRuntime/IReferenceProjection+Primitive.swift @@ -25,19 +25,19 @@ extension IReferenceProjection { public static var interfaceID: COMInterfaceID { switch Projection.self { - case is BoolProjection.Type: COMInterfaceID(0x3C00FD60, 0x2950, 0x5939, 0xA21A, 0x2D12C5A01B8A) - case is NumericProjection.Type: COMInterfaceID(0xE5198CC8, 0x2873, 0x55F5, 0xB0A1, 0x84FF9E4AAD62) - case is NumericProjection.Type: COMInterfaceID(0x6EC9E41B, 0x6709, 0x5647, 0x9918, 0xA1270110FC4E) - case is NumericProjection.Type: COMInterfaceID(0x5AB7D2C3, 0x6B62, 0x5E71, 0xA4B6, 0x2D49C4F238FD) - case is NumericProjection.Type: COMInterfaceID(0x548CEFBD, 0xBC8A, 0x5FA0, 0x8DF2, 0x957440FC8BF4) - case is NumericProjection.Type: COMInterfaceID(0x513EF3AF, 0xE784, 0x5325, 0xA91E, 0x97C2B8111CF3) - case is NumericProjection.Type: COMInterfaceID(0x4DDA9E24, 0xE69F, 0x5C6A, 0xA0A6, 0x93427365AF2A) - case is NumericProjection.Type: COMInterfaceID(0x6755E376, 0x53BB, 0x568B, 0xA11D, 0x17239868309E) - case is NumericProjection.Type: COMInterfaceID(0x719CC2BA, 0x3E76, 0x5DEF, 0x9F1A, 0x38D85A145EA8) - case is NumericProjection.Type: COMInterfaceID(0x2F2D6C29, 0x5473, 0x5F3E, 0x92E7, 0x96572BB990E2) - case is COM.WideCharProjection.Type: COMInterfaceID(0xFB393EF3, 0xBBAC, 0x5BD5, 0x9144, 0x84F23576F415) - case is HStringProjection.Type: COMInterfaceID(0xFD416DFB, 0x2A07, 0x52EB, 0xAAE3, 0xDFCE14116C05) - case is COM.GUIDProjection.Type: COMInterfaceID(0x7D50F649, 0x632C, 0x51F9, 0x849A, 0xEE49428933EA) + case is BoolProjection.Type: PrimitiveBoxing.IReferenceIDs.bool + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.uint8 + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.int16 + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.uint16 + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.int32 + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.uint32 + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.int64 + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.uint64 + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.single + case is NumericProjection.Type: PrimitiveBoxing.IReferenceIDs.double + case is COM.WideCharProjection.Type: PrimitiveBoxing.IReferenceIDs.char16 + case is HStringProjection.Type: PrimitiveBoxing.IReferenceIDs.string + case is COM.GUIDProjection.Type: PrimitiveBoxing.IReferenceIDs.guid default: fatalError("Invalid generic parameter: IReferenceProjection.Primitive<\(Projection.self)>") } } @@ -52,36 +52,37 @@ extension IReferenceProjection { return Projection.toSwift(value) } - public static func toABI(_ value: SwiftValue) throws -> ABIValue { - guard let value else { return nil } - - var propertyValue: UnsafeMutablePointer? = nil - defer { IInspectableProjection.release(&propertyValue) } + private static func box(_ value: Projection.SwiftValue) throws -> COMReference { switch value { - case let value as Swift.Bool: propertyValue = try propertyValueStatics.createBoolean(value) - case let value as Swift.UInt8: propertyValue = try propertyValueStatics.createUInt8(value) - case let value as Swift.Int16: propertyValue = try propertyValueStatics.createInt16(value) + case let value as Swift.Bool: return try PrimitiveBoxing.boolean(value) + case let value as Swift.UInt8: return try PrimitiveBoxing.uint8(value) + case let value as Swift.Int16: return try PrimitiveBoxing.int16(value) // UInt16 aka Unicode.UTF16.CodeUnit must be disambiguated from the projection type case let value as Swift.UInt16: - propertyValue = try Projection.self == COM.WideCharProjection.self - ? propertyValueStatics.createChar16(value) - : propertyValueStatics.createUInt16(value) + return try Projection.self == COM.WideCharProjection.self + ? PrimitiveBoxing.char16(value) + : PrimitiveBoxing.uint16(value) - case let value as Swift.Int32: propertyValue = try propertyValueStatics.createInt32(value) - case let value as Swift.UInt32: propertyValue = try propertyValueStatics.createUInt32(value) - case let value as Swift.Int64: propertyValue = try propertyValueStatics.createInt64(value) - case let value as Swift.UInt64: propertyValue = try propertyValueStatics.createUInt64(value) - case let value as Swift.Float: propertyValue = try propertyValueStatics.createSingle(value) - case let value as Swift.Double: propertyValue = try propertyValueStatics.createDouble(value) - case let value as Swift.String: propertyValue = try propertyValueStatics.createString(value) - case let value as Foundation.UUID: propertyValue = try propertyValueStatics.createGuid(value) + case let value as Swift.Int32: return try PrimitiveBoxing.int32(value) + case let value as Swift.UInt32: return try PrimitiveBoxing.uint32(value) + case let value as Swift.Int64: return try PrimitiveBoxing.int64(value) + case let value as Swift.UInt64: return try PrimitiveBoxing.uint64(value) + case let value as Swift.Float: return try PrimitiveBoxing.single(value) + case let value as Swift.Double: return try PrimitiveBoxing.double(value) + case let value as Swift.String: return try PrimitiveBoxing.string(value) + case let value as Foundation.UUID: return try PrimitiveBoxing.guid(value) default: throw HResult.Error.fail } + } - guard let propertyValue else { throw HResult.Error.noInterface } + public static func toABI(_ value: SwiftValue) throws -> ABIValue { + guard let value else { return nil } - return try IUnknownPointer.queryInterface(propertyValue, Self.interfaceID).cast(to: WindowsRuntime_ABI.SWRT_IReference.self) + let inspectable = try box(value) + return try inspectable.interop.queryInterface(Self.interfaceID) + .reinterpret(to: WindowsRuntime_ABI.SWRT_IReference.self) + .detach() } public static func release(_ value: inout ABIValue) { @@ -91,15 +92,3 @@ extension IReferenceProjection { } } } - -fileprivate var lazyPropertyValueStatics: COM.COMLazyReference = .init() - -internal var propertyValueStatics: COMInterop { - get throws { - try lazyPropertyValueStatics.getInterop { - try WinRTClassLoader.default.getActivationFactory( - runtimeClass: "Windows.Foundation.PropertyValue", - interfaceID: WindowsRuntime_ABI.SWRT_IPropertyValueStatics.iid) - } - } -} \ No newline at end of file diff --git a/Support/Sources/WindowsRuntime/PrimitiveBoxing.swift b/Support/Sources/WindowsRuntime/PrimitiveBoxing.swift new file mode 100644 index 00000000..9ef99a88 --- /dev/null +++ b/Support/Sources/WindowsRuntime/PrimitiveBoxing.swift @@ -0,0 +1,128 @@ +import COM +import WindowsRuntime_ABI +import struct Foundation.UUID + +internal enum PrimitiveBoxing { + private static let iid = COMInterfaceID(0x629BDBC8, 0xD932, 0x4FF4, 0x96B9, 0x8D96C5C1E858) + private static var lazyReference: COM.COMLazyReference = .init() + + private static var this: UnsafeMutablePointer { + get throws { + try lazyReference.getPointer { + try WinRTClassLoader.default.getActivationFactory( + runtimeClass: "Windows.Foundation.PropertyValue", + interfaceID: iid) + } + } + } + + public enum IReferenceIDs { + public static var bool: COMInterfaceID { COMInterfaceID(0x3C00FD60, 0x2950, 0x5939, 0xA21A, 0x2D12C5A01B8A) } + public static var uint8: COMInterfaceID { COMInterfaceID(0xE5198CC8, 0x2873, 0x55F5, 0xB0A1, 0x84FF9E4AAD62) } + public static var int16: COMInterfaceID { COMInterfaceID(0x6EC9E41B, 0x6709, 0x5647, 0x9918, 0xA1270110FC4E) } + public static var uint16: COMInterfaceID { COMInterfaceID(0x5AB7D2C3, 0x6B62, 0x5E71, 0xA4B6, 0x2D49C4F238FD) } + public static var int32: COMInterfaceID { COMInterfaceID(0x548CEFBD, 0xBC8A, 0x5FA0, 0x8DF2, 0x957440FC8BF4) } + public static var uint32: COMInterfaceID { COMInterfaceID(0x513EF3AF, 0xE784, 0x5325, 0xA91E, 0x97C2B8111CF3) } + public static var int64: COMInterfaceID { COMInterfaceID(0x4DDA9E24, 0xE69F, 0x5C6A, 0xA0A6, 0x93427365AF2A) } + public static var uint64: COMInterfaceID { COMInterfaceID(0x6755E376, 0x53BB, 0x568B, 0xA11D, 0x17239868309E) } + public static var single: COMInterfaceID { COMInterfaceID(0x719CC2BA, 0x3E76, 0x5DEF, 0x9F1A, 0x38D85A145EA8) } + public static var double: COMInterfaceID { COMInterfaceID(0x2F2D6C29, 0x5473, 0x5F3E, 0x92E7, 0x96572BB990E2) } + public static var char16: COMInterfaceID { COMInterfaceID(0xFB393EF3, 0xBBAC, 0x5BD5, 0x9144, 0x84F23576F415) } + public static var string: COMInterfaceID { COMInterfaceID(0xFD416DFB, 0x2A07, 0x52EB, 0xAAE3, 0xDFCE14116C05) } + public static var guid: COMInterfaceID { COMInterfaceID(0x7D50F649, 0x632C, 0x51F9, 0x849A, 0xEE49428933EA) } + } + + public static func uint8(_ value: UInt8) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateUInt8(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func int16(_ value: Int16) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateInt16(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func uint16(_ value: UInt16) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateUInt16(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func int32(_ value: Int32) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateInt32(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func uint32(_ value: UInt32) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateUInt32(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func int64(_ value: Int64) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateInt64(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func uint64(_ value: UInt64) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateUInt64(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func single(_ value: Float) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateSingle(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func double(_ value: Double) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateDouble(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func char16(_ value: UInt16) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateChar16(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func boolean(_ value: Bool) throws -> COMReference { + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateBoolean(this, value, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func string(_ value: String) throws -> COMReference { + var value_abi = try HStringProjection.toABI(value) + defer { HStringProjection.release(&value_abi) } + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateString(this, value_abi, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } + + public static func guid(_ value: UUID) throws -> COMReference { + let value_abi = COM.GUIDProjection.toABI(value) + var propertyValue: IInspectablePointer? = nil + try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateGuid(this, value_abi, &propertyValue)) + guard let propertyValue else { throw HResult.Error.pointer } + return COMReference(transferringRef: propertyValue) + } +} diff --git a/Support/Sources/WindowsRuntime/PropertyValueStatics.swift b/Support/Sources/WindowsRuntime/PropertyValueStatics.swift deleted file mode 100644 index 78c21410..00000000 --- a/Support/Sources/WindowsRuntime/PropertyValueStatics.swift +++ /dev/null @@ -1,95 +0,0 @@ -import COM -import WindowsRuntime_ABI -import struct Foundation.UUID - -#if swift(>=5.10) -extension WindowsRuntime_ABI.SWRT_IPropertyValueStatics: @retroactive COMIUnknownStruct {} -#endif - -extension WindowsRuntime_ABI.SWRT_IPropertyValueStatics: /* @retroactive */ COMIInspectableStruct { - public static let iid = COMInterfaceID(0x629BDBC8, 0xD932, 0x4FF4, 0x96B9, 0x8D96C5C1E858) -} - -extension COMInterop where Interface == WindowsRuntime_ABI.SWRT_IPropertyValueStatics { - // Special case to return the raw pointer since these act as factory methods - public func createUInt8(_ value: UInt8) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateUInt8(this, value, &propertyValue)) - return propertyValue - } - - public func createInt16(_ value: Int16) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateInt16(this, value, &propertyValue)) - return propertyValue - } - - public func createUInt16(_ value: UInt16) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateUInt16(this, value, &propertyValue)) - return propertyValue - } - - public func createInt32(_ value: Int32) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateInt32(this, value, &propertyValue)) - return propertyValue - } - - public func createUInt32(_ value: UInt32) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateUInt32(this, value, &propertyValue)) - return propertyValue - } - - public func createInt64(_ value: Int64) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateInt64(this, value, &propertyValue)) - return propertyValue - } - - public func createUInt64(_ value: UInt64) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateUInt64(this, value, &propertyValue)) - return propertyValue - } - - public func createSingle(_ value: Float) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateSingle(this, value, &propertyValue)) - return propertyValue - } - - public func createDouble(_ value: Double) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateDouble(this, value, &propertyValue)) - return propertyValue - } - - public func createChar16(_ value: UInt16) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateChar16(this, value, &propertyValue)) - return propertyValue - } - - public func createBoolean(_ value: Bool) throws -> IInspectablePointer? { - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateBoolean(this, value, &propertyValue)) - return propertyValue - } - - public func createString(_ value: String) throws -> IInspectablePointer? { - var value_abi = try HStringProjection.toABI(value) - defer { HStringProjection.release(&value_abi) } - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateString(this, value_abi, &propertyValue)) - return propertyValue - } - - public func createGuid(_ value: UUID) throws -> IInspectablePointer? { - let value_abi = COM.GUIDProjection.toABI(value) - var propertyValue: IInspectablePointer? = nil - try WinRTError.throwIfFailed(this.pointee.lpVtbl.pointee.CreateGuid(this, value_abi, &propertyValue)) - return propertyValue - } -} \ No newline at end of file