github.com/ebitengine/purego@v0.8.0-alpha.2.0.20240512170805-6cd12240d332/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  // CString converts a go string to *byte that can be passed to C code.
    16  func CString(name string) *byte {
    17  	if hasSuffix(name, "\x00") {
    18  		return &(*(*[]byte)(unsafe.Pointer(&name)))[0]
    19  	}
    20  	b := make([]byte, len(name)+1)
    21  	copy(b, name)
    22  	return &b[0]
    23  }
    24  
    25  // GoString copies a null-terminated char* to a Go string.
    26  func GoString(c uintptr) string {
    27  	// We take the address and then dereference it to trick go vet from creating a possible misuse of unsafe.Pointer
    28  	ptr := *(*unsafe.Pointer)(unsafe.Pointer(&c))
    29  	if ptr == nil {
    30  		return ""
    31  	}
    32  	var length int
    33  	for {
    34  		if *(*byte)(unsafe.Add(ptr, uintptr(length))) == '\x00' {
    35  			break
    36  		}
    37  		length++
    38  	}
    39  	return string(unsafe.Slice((*byte)(ptr), length))
    40  }