github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/unsafe/reflectx/unsafeheader.go (about) 1 package reflectx 2 3 import ( 4 "fmt" 5 "reflect" 6 "unsafe" 7 8 "github.com/jxskiss/gopkg/v2/internal/unsafeheader" 9 ) 10 11 // StringHeader is the runtime representation of a string. 12 // 13 // Unlike reflect.StringHeader, its Data field is sufficient to guarantee the 14 // data it references will not be garbage collected. 15 type StringHeader = unsafeheader.StringHeader 16 17 // SliceHeader is the runtime representation of a slice. 18 // 19 // Unlike reflect.SliceHeader, its Data field is sufficient to guarantee the 20 // data it references will not be garbage collected. 21 type SliceHeader = unsafeheader.SliceHeader 22 23 // EmptyInterface is the header for an interface{} value. 24 // It's a copy type of runtime.eface. 25 type EmptyInterface struct { 26 RType *RType // *rtype 27 Word unsafe.Pointer // data pointer 28 } 29 30 // StringToBytes converts a string to []byte without copying memory. 31 // 32 // It uses unsafe tricks, it may panic your program or result 33 // unpredictable behavior. 34 func StringToBytes(s string) []byte { 35 return unsafeheader.StringToBytes(s) 36 } 37 38 // BytesToString converts a []byte to string without copying memory. 39 // 40 // It uses unsafe tricks, it may panic your program or result 41 // unpredictable behavior. 42 func BytesToString(b []byte) string { 43 return unsafeheader.BytesToString(b) 44 } 45 46 // EfaceOf casts the empty interface{} pointer to an EmptyInterface pointer. 47 func EfaceOf(ep *any) EmptyInterface { 48 return *(*EmptyInterface)(unsafe.Pointer(ep)) 49 } 50 51 // UnpackSlice unpacks the given slice interface{} to the underlying 52 // EmptyInterface and SliceHeader. 53 // It panics if param slice is not a slice. 54 func UnpackSlice(slice any) (EmptyInterface, *SliceHeader) { 55 eface := EfaceOf(&slice) 56 if eface.RType.Kind() != reflect.Slice { 57 panic(invalidType("UnpackSlice", "slice", slice)) 58 } 59 header := (*SliceHeader)(eface.Word) 60 return eface, header 61 } 62 63 // SliceLen returns the length of the given slice interface{} value. 64 // The provided slice must be a slice, else it panics. 65 func SliceLen(slice any) int { 66 _, header := UnpackSlice(slice) 67 return header.Len 68 } 69 70 // SliceCap returns the capacity of the given slice interface{} value. 71 // The provided slice must be a slice, else it panics. 72 func SliceCap(slice any) int { 73 _, header := UnpackSlice(slice) 74 return header.Cap 75 } 76 77 func invalidType(where string, want string, got any) string { 78 const invalidType = "%s: invalid type, want %s, got %T" 79 return fmt.Sprintf(invalidType, where, want, got) 80 }