Utility functions to allow using string/[]byte interchangeably without copies

This commit is contained in:
Kovid Goyal 2022-09-02 13:30:52 +05:30
parent 61094c6bfb
commit 081390b5a2
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

45
tools/utils/unsafeutil.go Normal file
View File

@ -0,0 +1,45 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package utils
import (
"unsafe"
)
// stringHeader is the runtime representation of a string.
// It should be identical to reflect.StringHeader
type stringHeader struct {
data unsafe.Pointer
stringLen int
}
// sliceHeader is the runtime representation of a slice.
// It should be identical to reflect.sliceHeader
type sliceHeader struct {
data unsafe.Pointer
sliceLen int
sliceCap int
}
// Unsafely converts s into a byte slice.
// If you modify b, then s will also be modified. This violates the
// property that strings are immutable.
func UnsafeStringToBytes(s string) (b []byte) {
stringHeader := (*stringHeader)(unsafe.Pointer(&s))
sliceHeader := (*sliceHeader)(unsafe.Pointer(&b))
sliceHeader.data = stringHeader.data
sliceHeader.sliceLen = len(s)
sliceHeader.sliceCap = len(s)
return b
}
// Unsafely converts b into a string.
// If you modify b, then s will also be modified. This violates the
// property that strings are immutable.
func UnsafeBytesToString(b []byte) (s string) {
sliceHeader := (*sliceHeader)(unsafe.Pointer(&b))
stringHeader := (*stringHeader)(unsafe.Pointer(&s))
stringHeader.data = sliceHeader.data
stringHeader.stringLen = len(b)
return s
}