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  }