Skip to content
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

Remove importing C from conversions.go #97

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions tmpl/conversions.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ package {{.Name}}
import (
"fmt"
"reflect"
"runtime"
"strings"
"unsafe"
)

// #include <stdlib.h>
import "C"

// Ptr takes a slice or pointer (to a singular scalar value or the first
// element of an array or slice) and returns its GL-compatible address.
//
Expand Down Expand Up @@ -70,7 +68,15 @@ func Str(str string) *uint8 {
// GoStr takes a null-terminated string returned by OpenGL and constructs a
// corresponding Go string.
func GoStr(cstr *uint8) string {
return C.GoString((*C.char)(unsafe.Pointer(cstr)))
str := ""
for {
if *cstr == 0 {
break
}
str += string(*cstr)
cstr = (*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(cstr)) + 1))
}
return str
}

// Strs takes a list of Go strings (with or without null-termination) and
Expand All @@ -85,26 +91,18 @@ func Strs(strs ...string) (cstrs **uint8, free func()) {
panic("Strs: expected at least 1 string")
}

// Allocate a contiguous array large enough to hold all the strings' contents.
n := 0
for i := range strs {
n += len(strs[i])
pinned := []string{}
ptrs := []*uint8{}
for _, str := range strs {
if !strings.HasSuffix(str, "\x00") {
str += "\x00"
}
pinned = append(pinned, str)
ptrs = append(ptrs, Str(str))
}
data := C.malloc(C.size_t(n))

// Copy all the strings into data.
dataSlice := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(data),
Len: n,
Cap: n,
}))
css := make([]*uint8, len(strs)) // Populated with pointers to each string.
offset := 0
for i := range strs {
copy(dataSlice[offset:offset+len(strs[i])], strs[i][:]) // Copy strs[i] into proper data location.
css[i] = (*uint8)(unsafe.Pointer(&dataSlice[offset])) // Set a pointer to it.
offset += len(strs[i])
return &ptrs[0], func() {
runtime.KeepAlive(pinned)
pinned = nil
}

return (**uint8)(&css[0]), func() { C.free(data) }
}