github.com/urso/go-structform@v0.0.2/internal/unsafe/unsafe.go (about) 1 package unsafe 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type emptyInterface struct { 9 typ unsafe.Pointer 10 word unsafe.Pointer 11 } 12 13 func Str2Bytes(s string) []byte { 14 sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) 15 bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len} 16 b := *(*[]byte)(unsafe.Pointer(&bh)) 17 return b 18 } 19 20 func Bytes2Str(b []byte) string { 21 bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) 22 sh := reflect.StringHeader{Data: bh.Data, Len: bh.Len} 23 return *((*string)(unsafe.Pointer(&sh))) 24 } 25 26 // IfcValuePtr extracts the underlying values pointer from an empty interface{} 27 // value. 28 // Note: this might beome more unsafe in future go-versions, 29 // if primitive values < pointer size will be stored by value in the 30 // `interface{}` type. 31 func IfcValuePtr(v interface{}) unsafe.Pointer { 32 ifc := (*emptyInterface)(unsafe.Pointer(&v)) 33 return ifc.word 34 } 35 36 // ReflValuePtr extracts the pointer value from a reflect.Value instance. 37 // With reflect.Value basically being similar to `interface{}` augmented with additional 38 // flags to execute checks, we map the value into an empty interface value (no methods) 39 // and extract the actual values pointer. 40 // Note: this might beome more unsafe in future go-versions, 41 // if primitive values < pointer size will be stored by value in the 42 // `interface{}` type. 43 func ReflValuePtr(v reflect.Value) unsafe.Pointer { 44 ifc := (*emptyInterface)(unsafe.Pointer(&v)) 45 return ifc.word 46 } 47 48 // Returns a newly (allocated on heap) function pointer. The unsafe.Pointer returned 49 // can be used to cast a function type into a function with other(compatible) 50 // type (e.g. passing pointers only). 51 func UnsafeFnPtr(fn interface{}) unsafe.Pointer { 52 var v reflect.Value 53 if tmp, ok := fn.(reflect.Value); ok { 54 v = tmp 55 } else { 56 v = reflect.ValueOf(fn) 57 } 58 59 tmp := reflect.New(v.Type()) 60 tmp.Elem().Set(v) 61 return unsafe.Pointer(tmp.Pointer()) 62 }