Esempio n. 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))
}
Esempio n. 2
0
// QueryItem returns a list of query results.
func QueryItem(item Item) ([]QueryResult, error) {
	resultsRef, err := QueryItemRef(item)
	if err != nil {
		return nil, err
	}
	if resultsRef == nil {
		return nil, nil
	}
	defer Release(resultsRef)

	results := make([]QueryResult, 0, 1)

	typeID := C.CFGetTypeID(resultsRef)
	if typeID == C.CFArrayGetTypeID() {
		arr := CFArrayToArray(C.CFArrayRef(resultsRef))
		for _, ref := range arr {
			typeID := C.CFGetTypeID(ref)
			if typeID == C.CFDictionaryGetTypeID() {
				item, err := convertResult(C.CFDictionaryRef(ref))
				if err != nil {
					return nil, err
				}
				results = append(results, *item)
			} else {
				return nil, fmt.Errorf("Invalid result type (If you SetReturnRef(true) you should use QueryItemRef directly).")
			}
		}
	} else if typeID == C.CFDictionaryGetTypeID() {
		item, err := convertResult(C.CFDictionaryRef(resultsRef))
		if err != nil {
			return nil, err
		}
		results = append(results, *item)
	} else if typeID == C.CFDataGetTypeID() {
		b, err := CFDataToBytes(C.CFDataRef(resultsRef))
		if err != nil {
			return nil, err
		}
		item := QueryResult{Data: b}
		results = append(results, item)
	} else {
		return nil, fmt.Errorf("Invalid result type: %s", CFTypeDescription(resultsRef))
	}

	return results, nil
}
Esempio n. 3
0
// QueryItem returns a list of query results.
func QueryItem(item Item) ([]QueryResult, error) {
	cfDict, err := ConvertMapToCFDictionary(item.attr)
	if err != nil {
		return nil, err
	}
	defer Release(C.CFTypeRef(cfDict))

	var resultsRef C.CFTypeRef
	errCode := C.SecItemCopyMatching(cfDict, &resultsRef)
	if Error(errCode) == ErrorItemNotFound {
		return nil, nil
	}
	err = checkError(errCode)
	if err != nil {
		return nil, err
	}
	defer Release(resultsRef)

	results := make([]QueryResult, 0, 1)

	typeID := C.CFGetTypeID(resultsRef)
	if typeID == C.CFArrayGetTypeID() {
		arr := CFArrayToArray(C.CFArrayRef(resultsRef))
		for _, dictRef := range arr {
			item, err := convertResult(C.CFDictionaryRef(dictRef))
			if err != nil {
				return nil, err
			}
			results = append(results, *item)
		}
	} else if typeID == C.CFDictionaryGetTypeID() {
		item, err := convertResult(C.CFDictionaryRef(resultsRef))
		if err != nil {
			return nil, err
		}
		results = append(results, *item)
	} else if typeID == C.CFDataGetTypeID() {
		b, err := CFDataToBytes(C.CFDataRef(resultsRef))
		if err != nil {
			return nil, err
		}
		item := QueryResult{Data: b}
		results = append(results, item)
	} else {
		return nil, fmt.Errorf("Invalid result type: %s", CFTypeDescription(resultsRef))
	}

	return results, nil
}
Esempio n. 4
0
// 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}
}
Esempio n. 5
0
	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(""),
}

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