darwin: wrap cgo-types directly (without using a struct)
This makes easier the boxing/unboxing of the wrapped types.
This commit is contained in:
@@ -28,7 +28,7 @@ func nativeGetDetailedPortsList() ([]*PortDetails, error) {
|
||||
for _, service := range services {
|
||||
defer service.Release()
|
||||
|
||||
port, err := extractPortInfo(&io_registry_entry_t{ioregistryentry: service.ioobject})
|
||||
port, err := extractPortInfo(io_registry_entry_t(service))
|
||||
if err != nil {
|
||||
return nil, &PortEnumerationError{causedBy: err}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ func nativeGetDetailedPortsList() ([]*PortDetails, error) {
|
||||
return ports, nil
|
||||
}
|
||||
|
||||
func extractPortInfo(service *io_registry_entry_t) (*PortDetails, error) {
|
||||
func extractPortInfo(service io_registry_entry_t) (*PortDetails, error) {
|
||||
port := &PortDetails{}
|
||||
// If called too early the port may still not be ready or fully enumerated
|
||||
// so we retry 5 times before returning error.
|
||||
@@ -58,18 +58,12 @@ func extractPortInfo(service *io_registry_entry_t) (*PortDetails, error) {
|
||||
"IOUSBDevice": true,
|
||||
"IOUSBHostDevice": true,
|
||||
}
|
||||
|
||||
var (
|
||||
usbDevice = io_registry_entry_t{service.ioregistryentry}
|
||||
usbDeviceObj = io_object_t{usbDevice.ioregistryentry}
|
||||
searchErr error
|
||||
)
|
||||
|
||||
for !validUSBDeviceClass[usbDeviceObj.GetClass()] {
|
||||
usbDevice := service
|
||||
var searchErr error
|
||||
for !validUSBDeviceClass[usbDevice.GetClass()] {
|
||||
if usbDevice, searchErr = usbDevice.GetParent("IOService"); searchErr != nil {
|
||||
break
|
||||
}
|
||||
usbDeviceObj = io_object_t{usbDevice.ioregistryentry}
|
||||
}
|
||||
if searchErr == nil {
|
||||
// It's an IOUSBDevice
|
||||
@@ -100,7 +94,7 @@ func getAllServices(serviceType string) ([]io_object_t, error) {
|
||||
for tries < 5 {
|
||||
// Extract all elements from iterator
|
||||
if service, ok := i.Next(); ok {
|
||||
services = append(services, *service)
|
||||
services = append(services, service)
|
||||
continue
|
||||
}
|
||||
// If iterator is still valid return the result
|
||||
@@ -131,64 +125,57 @@ func getMatchingServices(matcher C.CFMutableDictionaryRef) (io_iterator_t, error
|
||||
var i C.io_iterator_t
|
||||
err := C.IOServiceGetMatchingServices(C.kIOMasterPortDefault, C.CFDictionaryRef(matcher), &i)
|
||||
if err != C.KERN_SUCCESS {
|
||||
return io_iterator_t{}, fmt.Errorf("IOServiceGetMatchingServices failed (code %d)", err)
|
||||
return 0, fmt.Errorf("IOServiceGetMatchingServices failed (code %d)", err)
|
||||
}
|
||||
return io_iterator_t{i}, nil
|
||||
return io_iterator_t(i), nil
|
||||
}
|
||||
|
||||
// cfStringRef
|
||||
// CFStringRef
|
||||
|
||||
type cfStringRef struct {
|
||||
cfs C.CFStringRef
|
||||
}
|
||||
type cfStringRef C.CFStringRef
|
||||
|
||||
func CFStringCreateWithString(s string) cfStringRef {
|
||||
func cfStringCreateWithString(s string) cfStringRef {
|
||||
c := C.CString(s)
|
||||
defer C.free(unsafe.Pointer(c))
|
||||
val := C.CFStringCreateWithCString(
|
||||
C.kCFAllocatorDefault, c, C.kCFStringEncodingMacRoman)
|
||||
return cfStringRef{val}
|
||||
return cfStringRef(C.CFStringCreateWithCString(
|
||||
C.kCFAllocatorDefault, c, C.kCFStringEncodingMacRoman))
|
||||
}
|
||||
|
||||
func (ref cfStringRef) Release() {
|
||||
C.CFRelease(C.CFTypeRef(ref.cfs))
|
||||
C.CFRelease(C.CFTypeRef(ref))
|
||||
}
|
||||
|
||||
// CFTypeRef
|
||||
|
||||
type cfTypeRef struct {
|
||||
cft C.CFTypeRef
|
||||
}
|
||||
type cfTypeRef C.CFTypeRef
|
||||
|
||||
func (ref cfTypeRef) Release() {
|
||||
C.CFRelease(C.CFTypeRef(ref.cft))
|
||||
C.CFRelease(C.CFTypeRef(ref))
|
||||
}
|
||||
|
||||
// io_registry_entry_t
|
||||
|
||||
type io_registry_entry_t struct {
|
||||
ioregistryentry C.io_registry_entry_t
|
||||
}
|
||||
type io_registry_entry_t C.io_registry_entry_t
|
||||
|
||||
func (me *io_registry_entry_t) GetParent(plane string) (io_registry_entry_t, error) {
|
||||
cPlane := C.CString(plane)
|
||||
defer C.free(unsafe.Pointer(cPlane))
|
||||
var parent C.io_registry_entry_t
|
||||
err := C.IORegistryEntryGetParentEntry(me.ioregistryentry, cPlane, &parent)
|
||||
err := C.IORegistryEntryGetParentEntry(C.io_registry_entry_t(*me), cPlane, &parent)
|
||||
if err != 0 {
|
||||
return io_registry_entry_t{}, errors.New("No parent device available")
|
||||
return 0, errors.New("No parent device available")
|
||||
}
|
||||
return io_registry_entry_t{parent}, nil
|
||||
return io_registry_entry_t(parent), nil
|
||||
}
|
||||
|
||||
func (me *io_registry_entry_t) CreateCFProperty(key string) (cfTypeRef, error) {
|
||||
k := CFStringCreateWithString(key)
|
||||
k := cfStringCreateWithString(key)
|
||||
defer k.Release()
|
||||
property := C.IORegistryEntryCreateCFProperty(me.ioregistryentry, k.cfs, C.kCFAllocatorDefault, 0)
|
||||
property := C.IORegistryEntryCreateCFProperty(C.io_registry_entry_t(*me), C.CFStringRef(k), C.kCFAllocatorDefault, 0)
|
||||
if property == 0 {
|
||||
return cfTypeRef{}, errors.New("Property not found: " + key)
|
||||
return 0, errors.New("Property not found: " + key)
|
||||
}
|
||||
return cfTypeRef{property}, nil
|
||||
return cfTypeRef(property), nil
|
||||
}
|
||||
|
||||
func (me *io_registry_entry_t) GetStringProperty(key string) (string, error) {
|
||||
@@ -199,13 +186,13 @@ func (me *io_registry_entry_t) GetStringProperty(key string) (string, error) {
|
||||
}
|
||||
defer property.Release()
|
||||
|
||||
if ptr := C.CFStringGetCStringPtr(C.CFStringRef(property.cft), 0); ptr != nil {
|
||||
if ptr := C.CFStringGetCStringPtr(C.CFStringRef(property), 0); ptr != nil {
|
||||
return C.GoString(ptr), nil
|
||||
}
|
||||
// in certain circumstances CFStringGetCStringPtr may return NULL
|
||||
// and we must retrieve the string by copy
|
||||
buff := make([]C.char, 1024)
|
||||
if C.CFStringGetCString(C.CFStringRef(property.cft), &buff[0], 1024, 0) != C.true {
|
||||
if C.CFStringGetCString(C.CFStringRef(property), &buff[0], 1024, 0) != C.true {
|
||||
return "", fmt.Errorf("Property '%s' can't be converted", key)
|
||||
}
|
||||
return C.GoString(&buff[0]), nil
|
||||
@@ -218,17 +205,25 @@ func (me *io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberType
|
||||
}
|
||||
defer property.Release()
|
||||
var res int
|
||||
if C.CFNumberGetValue((C.CFNumberRef)(property.cft), intType, unsafe.Pointer(&res)) != C.true {
|
||||
if C.CFNumberGetValue((C.CFNumberRef)(property), intType, unsafe.Pointer(&res)) != C.true {
|
||||
return res, fmt.Errorf("Property '%s' can't be converted or has been truncated", key)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (me *io_registry_entry_t) Release() {
|
||||
C.IOObjectRelease(C.io_object_t(*me))
|
||||
}
|
||||
|
||||
func (me *io_registry_entry_t) GetClass() string {
|
||||
class := make([]C.char, 1024)
|
||||
C.IOObjectGetClass(C.io_object_t(*me), &class[0])
|
||||
return C.GoString(&class[0])
|
||||
}
|
||||
|
||||
// io_iterator_t
|
||||
|
||||
type io_iterator_t struct {
|
||||
ioiterator C.io_iterator_t
|
||||
}
|
||||
type io_iterator_t C.io_iterator_t
|
||||
|
||||
// IsValid checks if an iterator is still valid.
|
||||
// Some iterators will be made invalid if changes are made to the
|
||||
@@ -236,34 +231,32 @@ type io_iterator_t struct {
|
||||
// is still valid and should be called when Next returns zero.
|
||||
// An invalid iterator can be Reset and the iteration restarted.
|
||||
func (me *io_iterator_t) IsValid() bool {
|
||||
return C.IOIteratorIsValid(me.ioiterator) == C.true
|
||||
return C.IOIteratorIsValid(C.io_iterator_t(*me)) == C.true
|
||||
}
|
||||
|
||||
func (me *io_iterator_t) Reset() {
|
||||
C.IOIteratorReset(me.ioiterator)
|
||||
C.IOIteratorReset(C.io_iterator_t(*me))
|
||||
}
|
||||
|
||||
func (me *io_iterator_t) Next() (*io_object_t, bool) {
|
||||
res := C.IOIteratorNext(me.ioiterator)
|
||||
return &io_object_t{res}, res != 0
|
||||
func (me *io_iterator_t) Next() (io_object_t, bool) {
|
||||
res := C.IOIteratorNext(C.io_iterator_t(*me))
|
||||
return io_object_t(res), res != 0
|
||||
}
|
||||
|
||||
func (me *io_iterator_t) Release() {
|
||||
C.IOObjectRelease(me.ioiterator)
|
||||
C.IOObjectRelease(C.io_object_t(*me))
|
||||
}
|
||||
|
||||
// io_object_t
|
||||
|
||||
type io_object_t struct {
|
||||
ioobject C.io_object_t
|
||||
}
|
||||
type io_object_t C.io_object_t
|
||||
|
||||
func (me *io_object_t) Release() {
|
||||
C.IOObjectRelease(me.ioobject)
|
||||
C.IOObjectRelease(C.io_object_t(*me))
|
||||
}
|
||||
|
||||
func (me *io_object_t) GetClass() string {
|
||||
class := make([]C.char, 1024)
|
||||
C.IOObjectGetClass(me.ioobject, &class[0])
|
||||
C.IOObjectGetClass(C.io_object_t(*me), &class[0])
|
||||
return C.GoString(&class[0])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user