Пример #1
0
// 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()
}
Пример #2
0
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
}
Пример #3
0
// Typeof returns the reflection Type of the value in the interface{}.
func Typeof(i interface{}) Type { return toType(unsafe.Typeof(i)) }
Пример #4
0
// Typeof returns the reflection Type of the value in the interface{}.
func Typeof(i interface{}) Type { return canonicalize(toType(unsafe.Typeof(i))) }