From 9aad86cc643a61a5f0b9d3324d5d9b405cff9734 Mon Sep 17 00:00:00 2001 From: vinocher-bc Date: Mon, 8 Apr 2024 17:32:18 -0700 Subject: [PATCH 1/4] Prevent a string copy while constructing HSTRING --- CMakePresets.json | 19 ++++++++++------ swiftwinrt/Resources/Support/HString.swift | 25 +++++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 6c9d953a..361f57a6 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -47,15 +47,20 @@ "CMAKE_CXX_COMPILER": "cl" } } - ], - "buildPresets": [ - { - "name": "debug", - "configurePreset": "debug" }, { "name": "release", "configurePreset": "release" } - ] -} + ], + "buildPresets": [ + { + "name": "debug", + "configurePreset": "debug" + }, + { + "name": "release", + "configurePreset": "release" + } + ] +} \ No newline at end of file diff --git a/swiftwinrt/Resources/Support/HString.swift b/swiftwinrt/Resources/Support/HString.swift index d7c7d2bb..5e8a3b9a 100644 --- a/swiftwinrt/Resources/Support/HString.swift +++ b/swiftwinrt/Resources/Support/HString.swift @@ -10,11 +10,26 @@ final public class HString { internal private(set) var hString: HSTRING? public init(_ string: String) throws { - self.hString = try string.withCString(encodedAs: UTF16.self) { - var result: HSTRING? - try CHECKED(WindowsCreateString($0, UINT32(wcslen($0)), &result)) - return result - } + + let codeUnitCount = string.utf16.count + var pointer: UnsafeMutablePointer? = nil + var hStringBuffer: HSTRING_BUFFER? = nil + + try CHECKED(WindowsPreallocateStringBuffer(UInt32(codeUnitCount), &pointer, &hStringBuffer)); + + guard let pointer else { throw Error(hr: E_FAIL) } + _ = UnsafeMutableBufferPointer(start: pointer, count: codeUnitCount).initialize(from: string.utf16) + + var hString: HSTRING? + do { + try CHECKED(WindowsPromoteStringBuffer(hStringBuffer, &hString)); + } + catch { + WindowsDeleteStringBuffer(hStringBuffer) + throw error + } + + self.hString = hString } public init(_ hString: HSTRING?) throws { From 36bcdd36e3cd911becc46356b14c28e82155f488 Mon Sep 17 00:00:00 2001 From: vinocher-bc Date: Mon, 8 Apr 2024 17:43:41 -0700 Subject: [PATCH 2/4] Fix test EXE directory --- .vscode/launch.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 6e47e5d7..675aa3eb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,18 +4,18 @@ "type": "swift-lldb", "request": "launch", "name": "test_app", - "program": "${workspaceFolder:swiftwinrt}\\out\\${command:cmake.activeBuildPresetName}\\bin\\test_app.exe", + "program": "${workspaceFolder}\\out\\${command:cmake.activeBuildPresetName}\\bin\\test_app.exe", "args": [], - "cwd": "${workspaceFolder:swiftwinrt}/tests", + "cwd": "${workspaceFolder}/tests", "preLaunchTask": "Install" }, { "type": "cppvsdbg", "request": "launch", "name": "test_app (pdb)", - "program": "${workspaceFolder:swiftwinrt}\\out\\${command:cmake.activeBuildPresetName}\\bin\\test_app", + "program": "${workspaceFolder}\\out\\${command:cmake.activeBuildPresetName}\\bin\\test_app", "args": [], - "cwd": "${workspaceFolder:swiftwinrt}/tests", + "cwd": "${workspaceFolder}/tests", "preLaunchTask": "Install" } ] From 536d782c1776eed3018e562f1099be1725c6af80 Mon Sep 17 00:00:00 2001 From: vinocher-bc Date: Tue, 9 Apr 2024 08:38:09 -0700 Subject: [PATCH 3/4] Fix rebase --- CMakePresets.json | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 361f57a6..6c9d953a 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -47,20 +47,15 @@ "CMAKE_CXX_COMPILER": "cl" } } + ], + "buildPresets": [ + { + "name": "debug", + "configurePreset": "debug" }, { "name": "release", "configurePreset": "release" } - ], - "buildPresets": [ - { - "name": "debug", - "configurePreset": "debug" - }, - { - "name": "release", - "configurePreset": "release" - } - ] -} \ No newline at end of file + ] +} From 8752645f6a11fbff9b0842fa6bd9ac8564f6a3e2 Mon Sep 17 00:00:00 2001 From: vinocher-bc Date: Tue, 9 Apr 2024 09:02:57 -0700 Subject: [PATCH 4/4] Fix indentation, narrow scope, add comments --- swiftwinrt/Resources/Support/HString.swift | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/swiftwinrt/Resources/Support/HString.swift b/swiftwinrt/Resources/Support/HString.swift index 5e8a3b9a..54e84d52 100644 --- a/swiftwinrt/Resources/Support/HString.swift +++ b/swiftwinrt/Resources/Support/HString.swift @@ -10,26 +10,25 @@ final public class HString { internal private(set) var hString: HSTRING? public init(_ string: String) throws { - let codeUnitCount = string.utf16.count var pointer: UnsafeMutablePointer? = nil var hStringBuffer: HSTRING_BUFFER? = nil + // Note: Methods like String.withCString are not used here because they do a copy to create a null + // terminated string, and requires an additional copy to create an HSTRING. Instead, a single copy is + // done by using WindowsPreallocateStringBuffer to allocate a buffer and directly copying the string into it. try CHECKED(WindowsPreallocateStringBuffer(UInt32(codeUnitCount), &pointer, &hStringBuffer)); - guard let pointer else { throw Error(hr: E_FAIL) } - _ = UnsafeMutableBufferPointer(start: pointer, count: codeUnitCount).initialize(from: string.utf16) - - var hString: HSTRING? - do { - try CHECKED(WindowsPromoteStringBuffer(hStringBuffer, &hString)); - } - catch { - WindowsDeleteStringBuffer(hStringBuffer) - throw error - } - - self.hString = hString + _ = UnsafeMutableBufferPointer(start: pointer, count: codeUnitCount).initialize(from: string.utf16) + + do { + var hString: HSTRING? = nil + try CHECKED(WindowsPromoteStringBuffer(hStringBuffer, &hString)); + self.hString = hString + } catch { + WindowsDeleteStringBuffer(hStringBuffer) + throw error + } } public init(_ hString: HSTRING?) throws {