// valueToXpc converts a go Value to an xpc object // // note that not all the types are supported, but only the subset required for Blued func valueToXpc(val r.Value) C.xpc_object_t { if !val.IsValid() { return nil } var xv C.xpc_object_t switch val.Kind() { case r.Int, r.Int8, r.Int16, r.Int32, r.Int64: xv = C.xpc_int64_create(C.int64_t(val.Int())) case r.Uint, r.Uint8, r.Uint16, r.Uint32: xv = C.xpc_int64_create(C.int64_t(val.Uint())) case r.String: xv = C.xpc_string_create(C.CString(val.String())) case r.Map: xv = C.xpc_dictionary_create(nil, nil, 0) for _, k := range val.MapKeys() { v := valueToXpc(val.MapIndex(k)) C.xpc_dictionary_set_value(xv, C.CString(k.String()), v) if v != nil { C.xpc_release(v) } } case r.Array, r.Slice: if val.Type() == TYPE_OF_UUID { // array of bytes var uuid [16]byte r.Copy(r.ValueOf(uuid[:]), val) xv = C.xpc_uuid_create(C.ptr_to_uuid(unsafe.Pointer(&uuid[0]))) } else if val.Type() == TYPE_OF_BYTES { // slice of bytes xv = C.xpc_data_create(unsafe.Pointer(val.Pointer()), C.size_t(val.Len())) } else { xv = C.xpc_array_create(nil, 0) l := val.Len() for i := 0; i < l; i++ { v := valueToXpc(val.Index(i)) C.xpc_array_append_value(xv, v) if v != nil { C.xpc_release(v) } } } case r.Interface, r.Ptr: xv = valueToXpc(val.Elem()) default: log.Fatalf("unsupported %#v", val.String()) } return xv }
// xpc_release is needed by tests, since they can't use CGO func xpc_release(xv C.xpc_object_t) { C.xpc_release(xv) }