github.com/jwijenbergh/purego@v0.0.0-20240126093400-70ff3a61df13/internal/strings/strings.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors 3 4 package strings 5 6 import ( 7 "unsafe" 8 ) 9 10 // hasSuffix tests whether the string s ends with suffix. 11 func hasSuffix(s, suffix string) bool { 12 return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix 13 } 14 15 func ByteSlice(name []string) **byte { 16 if name == nil { 17 return nil 18 } 19 res := make([]*byte, len(name)+1) 20 for i, v := range name { 21 res[i] = CString(v) 22 } 23 res[len(name)] = nil 24 return &res[0] 25 } 26 27 // CString converts a go string to *byte that can be passed to C code. 28 func CString(name string) *byte { 29 if hasSuffix(name, "\x00") { 30 return &(*(*[]byte)(unsafe.Pointer(&name)))[0] 31 } 32 b := make([]byte, len(name)+1) 33 copy(b, name) 34 return &b[0] 35 } 36 37 // GoString copies a null-terminated char* to a Go string. 38 func GoString(c uintptr) string { 39 // We take the address and then dereference it to trick go vet from creating a possible misuse of unsafe.Pointer 40 ptr := *(*unsafe.Pointer)(unsafe.Pointer(&c)) 41 if ptr == nil { 42 return "" 43 } 44 var length int 45 for { 46 if *(*byte)(unsafe.Add(ptr, uintptr(length))) == '\x00' { 47 break 48 } 49 length++ 50 } 51 return string(unsafe.Slice((*byte)(ptr), length)) 52 }