strings.go raw

   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  }
  41