-
Notifications
You must be signed in to change notification settings - Fork 107
cstrings: add NSStringToString #447
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
TotallyGamerJet
merged 8 commits into
ebitengine:main
from
TotallyGamerJet:#438_nsstring
May 9, 2026
+98
−0
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
63faf3f
nsstring
TotallyGamerJet 2b7b290
nsstrings: add NSStringToString
TotallyGamerJet e65606e
Merge branch 'main' into #438_nsstring
TotallyGamerJet 86c3846
fix panic package name
TotallyGamerJet 618ead6
license
TotallyGamerJet 4da8d9c
fix year
TotallyGamerJet d181d53
underscore in global variables
TotallyGamerJet b61728d
rename isKindOf
TotallyGamerJet File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | ||
|
|
||
| package cstrings | ||
|
|
||
| import ( | ||
| "fmt" | ||
|
|
||
| "github.com/ebitengine/purego" | ||
| "github.com/ebitengine/purego/internal/strings" | ||
| "github.com/ebitengine/purego/objc" | ||
| ) | ||
|
|
||
| var ( | ||
| sel_isKindOf objc.SEL | ||
| sel_UTF8String objc.SEL | ||
|
|
||
| class_NSString objc.Class | ||
|
hajimehoshi marked this conversation as resolved.
|
||
| ) | ||
|
|
||
| func init() { | ||
| // Must pull in Foundation to get the NSString class. | ||
| _, err := purego.Dlopen("/System/Library/Frameworks/Foundation.framework/Foundation", purego.RTLD_GLOBAL|purego.RTLD_NOW) | ||
| if err != nil { | ||
| panic(fmt.Errorf("cstrings: %w", err)) | ||
| } | ||
| sel_isKindOf = objc.RegisterName("isKindOfClass:") | ||
| sel_UTF8String = objc.RegisterName("UTF8String") | ||
| class_NSString = objc.GetClass("NSString") | ||
| } | ||
|
|
||
| // NSStringToString returns a copy of the NSString contents as a Go string. | ||
| // If the ID is 0 then an empty string is returned. | ||
| // If the ID is not an NSString class then the function panics. | ||
| // This function is only available on darwin. | ||
| func NSStringToString(str objc.ID) string { | ||
| if str == 0 { | ||
| return "" | ||
| } | ||
| if str.Send(sel_isKindOf, class_NSString) == 0 { | ||
| panic("cstrings: provided ID is not an NSString") | ||
| } | ||
| return strings.GoString(uintptr(str.Send(sel_UTF8String))) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | ||
|
|
||
| package cstrings_test | ||
|
TotallyGamerJet marked this conversation as resolved.
|
||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/ebitengine/purego/cstrings" | ||
| "github.com/ebitengine/purego/objc" | ||
| ) | ||
|
|
||
| func TestNSStringToString(t *testing.T) { | ||
| t.Run("nil ID returns empty string", func(t *testing.T) { | ||
| result := cstrings.NSStringToString(0) | ||
| if result != "" { | ||
| t.Errorf("expected empty string for nil ID, got %q", result) | ||
| } | ||
| }) | ||
|
|
||
| t.Run("valid NSString returns correct string", func(t *testing.T) { | ||
| sel := objc.RegisterName("stringWithUTF8String:") | ||
| nsString := objc.ID(objc.GetClass("NSString")).Send(sel, "Hello, World!\x00") | ||
|
|
||
|
hajimehoshi marked this conversation as resolved.
|
||
| result := cstrings.NSStringToString(nsString) | ||
| if result != "Hello, World!" { | ||
| t.Errorf("expected %q, got %q", "Hello, World!", result) | ||
| } | ||
| }) | ||
|
|
||
| t.Run("empty NSString returns empty string", func(t *testing.T) { | ||
| sel := objc.RegisterName("stringWithUTF8String:") | ||
| nsString := objc.ID(objc.GetClass("NSString")).Send(sel, "\x00") | ||
|
|
||
| result := cstrings.NSStringToString(nsString) | ||
| if result != "" { | ||
| t.Errorf("expected empty string, got %q", result) | ||
| } | ||
| }) | ||
|
|
||
| t.Run("non-NSString panics", func(t *testing.T) { | ||
| defer func() { | ||
| if r := recover(); r == nil { | ||
| t.Error("expected panic for non-NSString ID") | ||
| } | ||
| }() | ||
|
|
||
| classNSNumber := objc.GetClass("NSNumber") | ||
| sel := objc.RegisterName("numberWithInt:") | ||
| nsNumber := objc.ID(classNSNumber).Send(sel, 42) | ||
|
|
||
| cstrings.NSStringToString(nsNumber) | ||
|
hajimehoshi marked this conversation as resolved.
|
||
| }) | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.