// PtrTo returns the pointer type with element t. // For example, if t represents type Foo, PtrTo(t) represents *Foo. func PtrTo(t Type) Type { // If t records its pointer-to type, use it. ct := t.(*commonType) if p := ct.ptrToThis; p != nil { return toType(p) } // Otherwise, synthesize one. // This only happens for pointers with no methods. // We keep the mapping in a map on the side, because // this operation is rare and a separate map lets us keep // the type structures in read-only memory. ptrMap.RLock() if m := ptrMap.m; m != nil { if p := m[ct]; p != nil { ptrMap.RUnlock() return p.commonType.toType() } } ptrMap.RUnlock() ptrMap.Lock() if ptrMap.m == nil { ptrMap.m = make(map[*commonType]*ptrType) } p := ptrMap.m[ct] if p != nil { // some other goroutine won the race and created it ptrMap.Unlock() return p } rt := (*runtime.Type)(unsafe.Pointer(ct)) rp := new(runtime.PtrType) // initialize p using *byte's ptrType as a prototype. // have to do assignment as ptrType, not runtime.PtrType, // in order to write to unexported fields. p = (*ptrType)(unsafe.Pointer(rp)) bp := (*ptrType)(unsafe.Pointer(unsafe.Typeof((*byte)(nil)).(*runtime.PtrType))) *p = *bp s := "*" + *ct.string p.string = &s // For the type structures linked into the binary, the // compiler provides a good hash of the string. // Create a good hash for the new string by using // the FNV-1 hash's mixing function to combine the // old hash and the new "*". p.hash = ct.hash*16777619 ^ '*' p.uncommonType = nil p.ptrToThis = nil p.elem = (*runtime.Type)(unsafe.Pointer(ct)) ptrMap.m[ct] = p ptrMap.Unlock() return p.commonType.toType() }
func (ctx *Context) GetDeviceList() (dev []*Device, err *UsbError) { var ( baseptr **C.struct_libusb_device devlist []*C.struct_libusb_device ) count, err := decodeUsbError(C.int(C.libusb_get_device_list(ctx.ctx, &baseptr))) if err != nil { dev = nil return } hdr := &reflect.SliceHeader{Data: uintptr(unsafe.Pointer(baseptr)), Len: count, Cap: count} devlist = unsafe.Unreflect(unsafe.Typeof(devlist), unsafe.Pointer(&hdr)).([]*C.struct_libusb_device) dev = make([]*Device, count) for i := 0; i < count; i++ { dev[i] = ctx.wrapDevice(devlist[i]) } devlist = nil C.libusb_free_device_list(baseptr, 1) return dev, nil }
// Typeof returns the reflection Type of the value in the interface{}. func Typeof(i interface{}) Type { return toType(unsafe.Typeof(i)) }
// Typeof returns the reflection Type of the value in the interface{}. func Typeof(i interface{}) Type { return canonicalize(toType(unsafe.Typeof(i))) }