예제 #1
0
// 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))
}
예제 #2
0
func getCFDictValueCFStringRef(dict C.CFDictionaryRef, key C.CFTypeRef) (C.CFStringRef, error) {
	val, err := getCFDictValueRef(dict, key)
	if err != nil {
		return nil, err
	}
	if val == nil {
		return nil, errors.New("getCFDictValueCFStringRef: Nil value returned")
	}

	if C.CFGetTypeID(val) != C.CFStringGetTypeID() {
		return nil, errors.New("getCFDictValueCFStringRef: value is not a string")
	}

	return C.CFStringRef(val), nil
}
예제 #3
0
파일: convert.go 프로젝트: jcf/go-osx-plist
func convertCFDictionaryToMapHelper(cfDict C.CFDictionaryRef, helper func(key string, value cfTypeRef, count int) error) error {
	count := int(C.CFDictionaryGetCount(cfDict))
	if count == 0 {
		return nil
	}
	cfKeys := make([]cfTypeRef, count)
	cfVals := make([]cfTypeRef, count)
	C.CFDictionaryGetKeysAndValues(cfDict, (*unsafe.Pointer)(&cfKeys[0]), (*unsafe.Pointer)(&cfVals[0]))
	for i := 0; i < count; i++ {
		cfKey := cfKeys[i]
		typeId := C.CFGetTypeID(C.CFTypeRef(cfKey))
		if typeId != C.CFStringGetTypeID() {
			return &UnsupportedKeyTypeError{int(typeId)}
		}
		key := convertCFStringToString(C.CFStringRef(cfKey))
		if err := helper(key, cfVals[i], count); err != nil {
			return err
		}
	}
	return nil
}
예제 #4
0
파일: convert.go 프로젝트: jcf/go-osx-plist
// 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}
}
예제 #5
0
	}
	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(""),
}

var cfTypeNames = map[C.CFTypeID]string{
	cfArrayTypeID:      "CFArray",
	cfBooleanTypeID:    "CFBoolean",
	cfDataTypeID:       "CFData",