Merge pull request #163 from deadprogram/define-darwin-cgo-types
darwin: use Go type wrappers to avoid declaring Go methods on C types.
This commit is contained in:
@@ -28,7 +28,7 @@ func nativeGetDetailedPortsList() ([]*PortDetails, error) {
|
|||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
defer service.Release()
|
defer service.Release()
|
||||||
|
|
||||||
port, err := extractPortInfo(C.io_registry_entry_t(service))
|
port, err := extractPortInfo(io_registry_entry_t(service))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &PortEnumerationError{causedBy: err}
|
return nil, &PortEnumerationError{causedBy: err}
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ func nativeGetDetailedPortsList() ([]*PortDetails, error) {
|
|||||||
return ports, nil
|
return ports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractPortInfo(service C.io_registry_entry_t) (*PortDetails, error) {
|
func extractPortInfo(service io_registry_entry_t) (*PortDetails, error) {
|
||||||
port := &PortDetails{}
|
port := &PortDetails{}
|
||||||
// If called too early the port may still not be ready or fully enumerated
|
// If called too early the port may still not be ready or fully enumerated
|
||||||
// so we retry 5 times before returning error.
|
// so we retry 5 times before returning error.
|
||||||
@@ -82,14 +82,14 @@ func extractPortInfo(service C.io_registry_entry_t) (*PortDetails, error) {
|
|||||||
return port, nil
|
return port, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAllServices(serviceType string) ([]C.io_object_t, error) {
|
func getAllServices(serviceType string) ([]io_object_t, error) {
|
||||||
i, err := getMatchingServices(serviceMatching(serviceType))
|
i, err := getMatchingServices(serviceMatching(serviceType))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer i.Release()
|
defer i.Release()
|
||||||
|
|
||||||
var services []C.io_object_t
|
var services []io_object_t
|
||||||
tries := 0
|
tries := 0
|
||||||
for tries < 5 {
|
for tries < 5 {
|
||||||
// Extract all elements from iterator
|
// Extract all elements from iterator
|
||||||
@@ -105,7 +105,7 @@ func getAllServices(serviceType string) ([]C.io_object_t, error) {
|
|||||||
for _, s := range services {
|
for _, s := range services {
|
||||||
s.Release()
|
s.Release()
|
||||||
}
|
}
|
||||||
services = []C.io_object_t{}
|
services = []io_object_t{}
|
||||||
i.Reset()
|
i.Reset()
|
||||||
tries++
|
tries++
|
||||||
}
|
}
|
||||||
@@ -121,58 +121,64 @@ func serviceMatching(serviceType string) C.CFMutableDictionaryRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getMatchingServices look up registered IOService objects that match a matching dictionary.
|
// getMatchingServices look up registered IOService objects that match a matching dictionary.
|
||||||
func getMatchingServices(matcher C.CFMutableDictionaryRef) (C.io_iterator_t, error) {
|
func getMatchingServices(matcher C.CFMutableDictionaryRef) (io_iterator_t, error) {
|
||||||
var i C.io_iterator_t
|
var i C.io_iterator_t
|
||||||
err := C.IOServiceGetMatchingServices(C.kIOMasterPortDefault, C.CFDictionaryRef(matcher), &i)
|
err := C.IOServiceGetMatchingServices(C.kIOMasterPortDefault, C.CFDictionaryRef(matcher), &i)
|
||||||
if err != C.KERN_SUCCESS {
|
if err != C.KERN_SUCCESS {
|
||||||
return 0, fmt.Errorf("IOServiceGetMatchingServices failed (code %d)", err)
|
return 0, fmt.Errorf("IOServiceGetMatchingServices failed (code %d)", err)
|
||||||
}
|
}
|
||||||
return i, nil
|
return io_iterator_t(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFStringRef
|
// CFStringRef
|
||||||
|
|
||||||
func cfStringCreateWithString(s string) C.CFStringRef {
|
type cfStringRef C.CFStringRef
|
||||||
|
|
||||||
|
func cfStringCreateWithString(s string) cfStringRef {
|
||||||
c := C.CString(s)
|
c := C.CString(s)
|
||||||
defer C.free(unsafe.Pointer(c))
|
defer C.free(unsafe.Pointer(c))
|
||||||
return C.CFStringCreateWithCString(
|
return cfStringRef(C.CFStringCreateWithCString(
|
||||||
C.kCFAllocatorDefault, c, C.kCFStringEncodingMacRoman)
|
C.kCFAllocatorDefault, c, C.kCFStringEncodingMacRoman))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ref C.CFStringRef) Release() {
|
func (ref cfStringRef) Release() {
|
||||||
C.CFRelease(C.CFTypeRef(ref))
|
C.CFRelease(C.CFTypeRef(ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFTypeRef
|
// CFTypeRef
|
||||||
|
|
||||||
func (ref C.CFTypeRef) Release() {
|
type cfTypeRef C.CFTypeRef
|
||||||
C.CFRelease(ref)
|
|
||||||
|
func (ref cfTypeRef) Release() {
|
||||||
|
C.CFRelease(C.CFTypeRef(ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
// io_registry_entry_t
|
// io_registry_entry_t
|
||||||
|
|
||||||
func (me *C.io_registry_entry_t) GetParent(plane string) (C.io_registry_entry_t, error) {
|
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)
|
cPlane := C.CString(plane)
|
||||||
defer C.free(unsafe.Pointer(cPlane))
|
defer C.free(unsafe.Pointer(cPlane))
|
||||||
var parent C.io_registry_entry_t
|
var parent C.io_registry_entry_t
|
||||||
err := C.IORegistryEntryGetParentEntry(*me, cPlane, &parent)
|
err := C.IORegistryEntryGetParentEntry(C.io_registry_entry_t(*me), cPlane, &parent)
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
return 0, errors.New("No parent device available")
|
return 0, errors.New("No parent device available")
|
||||||
}
|
}
|
||||||
return parent, nil
|
return io_registry_entry_t(parent), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *C.io_registry_entry_t) CreateCFProperty(key string) (C.CFTypeRef, error) {
|
func (me *io_registry_entry_t) CreateCFProperty(key string) (cfTypeRef, error) {
|
||||||
k := cfStringCreateWithString(key)
|
k := cfStringCreateWithString(key)
|
||||||
defer k.Release()
|
defer k.Release()
|
||||||
property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0)
|
property := C.IORegistryEntryCreateCFProperty(C.io_registry_entry_t(*me), C.CFStringRef(k), C.kCFAllocatorDefault, 0)
|
||||||
if property == 0 {
|
if property == 0 {
|
||||||
return 0, errors.New("Property not found: " + key)
|
return 0, errors.New("Property not found: " + key)
|
||||||
}
|
}
|
||||||
return property, nil
|
return cfTypeRef(property), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) {
|
func (me *io_registry_entry_t) GetStringProperty(key string) (string, error) {
|
||||||
property, err := me.CreateCFProperty(key)
|
property, err := me.CreateCFProperty(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -191,7 +197,7 @@ func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) {
|
|||||||
return C.GoString(&buff[0]), nil
|
return C.GoString(&buff[0]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberType) (int, error) {
|
func (me *io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberType) (int, error) {
|
||||||
property, err := me.CreateCFProperty(key)
|
property, err := me.CreateCFProperty(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -204,34 +210,52 @@ func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberTy
|
|||||||
return res, nil
|
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
|
// io_iterator_t
|
||||||
|
|
||||||
|
type io_iterator_t C.io_iterator_t
|
||||||
|
|
||||||
// IsValid checks if an iterator is still valid.
|
// IsValid checks if an iterator is still valid.
|
||||||
// Some iterators will be made invalid if changes are made to the
|
// Some iterators will be made invalid if changes are made to the
|
||||||
// structure they are iterating over. This function checks the iterator
|
// structure they are iterating over. This function checks the iterator
|
||||||
// is still valid and should be called when Next returns zero.
|
// is still valid and should be called when Next returns zero.
|
||||||
// An invalid iterator can be Reset and the iteration restarted.
|
// An invalid iterator can be Reset and the iteration restarted.
|
||||||
func (me *C.io_iterator_t) IsValid() bool {
|
func (me *io_iterator_t) IsValid() bool {
|
||||||
return C.IOIteratorIsValid(*me) == C.true
|
return C.IOIteratorIsValid(C.io_iterator_t(*me)) == C.true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *C.io_iterator_t) Reset() {
|
func (me *io_iterator_t) Reset() {
|
||||||
C.IOIteratorReset(*me)
|
C.IOIteratorReset(C.io_iterator_t(*me))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *C.io_iterator_t) Next() (C.io_object_t, bool) {
|
func (me *io_iterator_t) Next() (io_object_t, bool) {
|
||||||
res := C.IOIteratorNext(*me)
|
res := C.IOIteratorNext(C.io_iterator_t(*me))
|
||||||
return res, res != 0
|
return io_object_t(res), res != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *io_iterator_t) Release() {
|
||||||
|
C.IOObjectRelease(C.io_object_t(*me))
|
||||||
}
|
}
|
||||||
|
|
||||||
// io_object_t
|
// io_object_t
|
||||||
|
|
||||||
func (me *C.io_object_t) Release() {
|
type io_object_t C.io_object_t
|
||||||
C.IOObjectRelease(*me)
|
|
||||||
|
func (me *io_object_t) Release() {
|
||||||
|
C.IOObjectRelease(C.io_object_t(*me))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *C.io_object_t) GetClass() string {
|
func (me *io_object_t) GetClass() string {
|
||||||
class := make([]C.char, 1024)
|
class := make([]C.char, 1024)
|
||||||
C.IOObjectGetClass(*me, &class[0])
|
C.IOObjectGetClass(C.io_object_t(*me), &class[0])
|
||||||
return C.GoString(&class[0])
|
return C.GoString(&class[0])
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user