github.com/prebid/prebid-server/v2@v2.18.0/util/reflectutil/slice.go (about) 1 package reflectutil 2 3 import ( 4 "unsafe" 5 6 "github.com/modern-go/reflect2" 7 ) 8 9 // UnsafeSliceClone clones an existing slice using unsafe.Pointer conventions. Intended 10 // for use by json iterator extensions and should likely be used no where else. Nil 11 // behavior is undefined as checks are expected upstream. 12 func UnsafeSliceClone(ptr unsafe.Pointer, sliceType reflect2.SliceType) unsafe.Pointer { 13 // it's also possible to use `sliceType.Elem().RType`, but that returns a `uintptr` 14 // which causes `go vet` to emit a warning even though the usage is safe. this approach 15 // of copying some internals from the reflect2 package avoids the cast of `uintptr` to 16 // `unsafe.Pointer` which keeps `go vet` output clean. 17 elemRType := unpackEFace(sliceType.Elem().Type1()).data 18 19 header := (*sliceHeader)(ptr) 20 newHeader := (*sliceHeader)(sliceType.UnsafeMakeSlice(header.Len, header.Cap)) 21 typedslicecopy(elemRType, *newHeader, *header) 22 return unsafe.Pointer(newHeader) 23 } 24 25 // sliceHeader is copied from the reflect2 package v1.0.2. 26 type sliceHeader struct { 27 Data unsafe.Pointer 28 Len int 29 Cap int 30 } 31 32 // typedslicecopyis copied from the reflect2 package v1.0.2. 33 // it copies a slice of elemType values from src to dst, 34 // returning the number of elements copied. 35 // 36 //go:linkname typedslicecopy reflect.typedslicecopy 37 //go:noescape 38 func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int 39 40 // eface is copied from the reflect2 package v1.0.2. 41 type eface struct { 42 rtype unsafe.Pointer 43 data unsafe.Pointer 44 } 45 46 // unpackEFace is copied from the reflect2 package v1.0.2. 47 func unpackEFace(obj interface{}) *eface { 48 return (*eface)(unsafe.Pointer(&obj)) 49 }