func convertCFStringToString(cfStr C.CFStringRef) string { cstrPtr := C.CFStringGetCStringPtr(cfStr, C.kCFStringEncodingUTF8) if cstrPtr != nil { return C.GoString(cstrPtr) } // quick path doesn't work, so copy the bytes out to a buffer length := C.CFStringGetLength(cfStr) if length == 0 { // short-cut for empty strings return "" } cfRange := C.CFRange{0, length} enc := C.CFStringEncoding(C.kCFStringEncodingUTF8) // first find the buffer size necessary var usedBufLen C.CFIndex if C.CFStringGetBytes(cfStr, cfRange, enc, 0, C.false, nil, 0, &usedBufLen) > 0 { bytes := make([]byte, usedBufLen) buffer := (*C.UInt8)(unsafe.Pointer(&bytes[0])) if C.CFStringGetBytes(cfStr, cfRange, enc, 0, C.false, buffer, usedBufLen, nil) > 0 { // bytes is now filled up // convert it to a string header := (*reflect.SliceHeader)(unsafe.Pointer(&bytes)) strHeader := &reflect.StringHeader{ Data: header.Data, Len: header.Len, } return *(*string)(unsafe.Pointer(strHeader)) } } // we failed to convert, for some reason. Too bad there's no nil string return "" }
func (ke keychainError) Error() string { errorMessageCFString := C.SecCopyErrorMessageString(C.OSStatus(ke), nil) defer C.CFRelease(C.CFTypeRef(errorMessageCFString)) errorMessageCString := C.CFStringGetCStringPtr(errorMessageCFString, C.kCFStringEncodingASCII) if errorMessageCString != nil { return C.GoString(errorMessageCString) } return fmt.Sprintf("keychainError with unknown error code %d", C.OSStatus(ke)) }
func (object Object) getStringProperty(key C.CFStringRef) (propValue string) { var result C.CFStringRef osStatus := C.MIDIObjectGetStringProperty(object.object, key, &result) if osStatus != C.noErr { return } defer C.CFRelease((C.CFTypeRef)(result)) value := C.CFStringGetCStringPtr(result, C.kCFStringEncodingMacRoman) propValue = C.GoString(value) return }
// CFStringToString converts a CFStringRef to a string. func CFStringToString(s C.CFStringRef) string { p := C.CFStringGetCStringPtr(s, C.kCFStringEncodingUTF8) if p != nil { return C.GoString(p) } length := C.CFStringGetLength(s) if length == 0 { return "" } maxBufLen := C.CFStringGetMaximumSizeForEncoding(length, C.kCFStringEncodingUTF8) if maxBufLen == 0 { return "" } buf := make([]byte, maxBufLen) var usedBufLen C.CFIndex _ = C.CFStringGetBytes(s, C.CFRange{0, length}, C.kCFStringEncodingUTF8, C.UInt8(0), C.false, (*C.UInt8)(&buf[0]), maxBufLen, &usedBufLen) return string(buf[:usedBufLen]) }
// Converts a CGStringRef object to a Go string. func CFStringToGoString(s C.CFStringRef) string { ptr := C.CFStringGetCStringPtr(s, C.kCFStringEncodingUTF8) if ptr != nil { return C.GoString(ptr) } n := C.CFStringGetLength(s) b := make([]byte, int(4*n)) C.CFStringGetBytes( s, C.CFRangeMake(0, n), C.kCFStringEncodingUTF8, '?', 0, (*C.UInt8)(unsafe.Pointer(&b[0])), C.CFIndex(len(b)), &n, ) return string(b[:n]) }