// Convert converts a CFTypeRef to a go instance. func Convert(ref C.CFTypeRef) (interface{}, error) { typeID := C.CFGetTypeID(ref) if typeID == C.CFStringGetTypeID() { return CFStringToString(C.CFStringRef(ref)), nil } else if typeID == C.CFDictionaryGetTypeID() { return ConvertCFDictionary(C.CFDictionaryRef(ref)) } else if typeID == C.CFArrayGetTypeID() { arr := CFArrayToArray(C.CFArrayRef(ref)) results := make([]interface{}, 0, len(arr)) for _, ref := range arr { v, err := Convert(ref) if err != nil { return nil, err } results = append(results, v) return results, nil } } else if typeID == C.CFDataGetTypeID() { b, err := CFDataToBytes(C.CFDataRef(ref)) if err != nil { return nil, err } return b, nil } else if typeID == C.CFNumberGetTypeID() { return CFNumberToInterface(C.CFNumberRef(ref)), nil } else if typeID == C.CFBooleanGetTypeID() { if C.CFBooleanGetValue(C.CFBooleanRef(ref)) != 0 { return true, nil } return false, nil } return nil, fmt.Errorf("Invalid type: %s", CFTypeDescription(ref)) }
// we shouldn't ever get an error from this, but I'd rather not panic func convertCFTypeToInterface(cfType cfTypeRef) (interface{}, error) { typeId := C.CFGetTypeID(C.CFTypeRef(cfType)) switch typeId { case C.CFStringGetTypeID(): return convertCFStringToString(C.CFStringRef(cfType)), nil case C.CFNumberGetTypeID(): return convertCFNumberToInterface(C.CFNumberRef(cfType)), nil case C.CFBooleanGetTypeID(): return convertCFBooleanToBool(C.CFBooleanRef(cfType)), nil case C.CFDataGetTypeID(): return convertCFDataToBytes(C.CFDataRef(cfType)), nil case C.CFDateGetTypeID(): return convertCFDateToTime(C.CFDateRef(cfType)), nil case C.CFArrayGetTypeID(): ary, err := convertCFArrayToSlice(C.CFArrayRef(cfType)) return ary, err case C.CFDictionaryGetTypeID(): dict, err := convertCFDictionaryToMap(C.CFDictionaryRef(cfType)) return dict, err } return nil, &UnknownCFTypeError{typeId} }
return format, &InvalidUnmarshalError{reflect.TypeOf(v)} } state := &unmarshalState{} if err := state.unmarshalValue(cfObj, rv); err != nil { return format, err } return format, state.err } type unmarshalState struct { err error } var ( cfArrayTypeID = C.CFArrayGetTypeID() cfBooleanTypeID = C.CFBooleanGetTypeID() cfDataTypeID = C.CFDataGetTypeID() cfDateTypeID = C.CFDateGetTypeID() cfDictionaryTypeID = C.CFDictionaryGetTypeID() cfNumberTypeID = C.CFNumberGetTypeID() cfStringTypeID = C.CFStringGetTypeID() ) var cfTypeMap = map[C.CFTypeID]reflect.Type{ cfArrayTypeID: reflect.TypeOf([]interface{}(nil)), cfBooleanTypeID: reflect.TypeOf(false), cfDataTypeID: reflect.TypeOf([]byte(nil)), cfDateTypeID: reflect.TypeOf(time.Time{}), cfDictionaryTypeID: reflect.TypeOf(map[string]interface{}(nil)), cfStringTypeID: reflect.TypeOf(""), }