Exemplo n.º 1
0
// xpcToGo converts an xpc object to a go object
//
// note that not all the types are supported, but only the subset required for Blued
func xpcToGo(v C.xpc_object_t) interface{} {
	t := C.xpc_get_type(v)

	switch t {
	case C.TYPE_ARRAY:
		a := make(Array, C.int(C.xpc_array_get_count(v)))
		C.XpcArrayApply(unsafe.Pointer(&a), v)
		return a

	case C.TYPE_DATA:
		return C.GoBytes(C.xpc_data_get_bytes_ptr(v), C.int(C.xpc_data_get_length(v)))

	case C.TYPE_DICT:
		d := make(Dict)
		C.XpcDictApply(unsafe.Pointer(&d), v)
		return d

	case C.TYPE_INT64:
		return int64(C.xpc_int64_get_value(v))

	case C.TYPE_STRING:
		return C.GoString(C.xpc_string_get_string_ptr(v))

	case C.TYPE_UUID:
		a := [16]byte{}
		C.XpcUUIDGetBytes(unsafe.Pointer(&a), v)
		return UUID(a[:])

	default:
		log.Fatalf("unexpected type %#v, value %#v", t, v)
	}

	return nil
}
Exemplo n.º 2
0
//export handleXpcEvent
func handleXpcEvent(event C.xpc_object_t, p unsafe.Pointer) {
	//log.Printf("handleXpcEvent %#v %#v\n", event, p)

	t := C.xpc_get_type(event)
	eh := *((*XpcEventHandler)(p))

	if t == C.TYPE_ERROR {
		if event == C.ERROR_CONNECTION_INVALID {
			// The client process on the other end of the connection has either
			// crashed or cancelled the connection. After receiving this error,
			// the connection is in an invalid state, and you do not need to
			// call xpc_connection_cancel(). Just tear down any associated state
			// here.
			//log.Println("connection invalid")
			eh.HandleXpcEvent(nil, CONNECTION_INVALID)
		} else if event == C.ERROR_CONNECTION_INTERRUPTED {
			//log.Println("connection interrupted")
			eh.HandleXpcEvent(nil, CONNECTION_INTERRUPTED)
		} else if event == C.ERROR_CONNECTION_TERMINATED {
			// Handle per-connection termination cleanup.
			//log.Println("connection terminated")
			eh.HandleXpcEvent(nil, CONNECTION_TERMINATED)
		} else {
			//log.Println("got some error", event)
			eh.HandleXpcEvent(nil, fmt.Errorf("%v", event))
		}
	} else {
		eh.HandleXpcEvent(xpcToGo(event).(Dict), nil)
	}
}