Esempio n. 1
0
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 ""
}
Esempio n. 2
0
func NSStringToString(inString Object) string {
	cr := C.CFStringRef(unsafe.Pointer(inString))

	var usedBufLen C.CFIndex
	rng := C.CFRange{C.CFIndex(0), C.CFStringGetLength(cr)}
	n := int(C.CFStringGetBytes(cr, rng, C.kCFStringEncodingUTF8, 0, 0, nil, 0, &usedBufLen))
	if n <= 0 {
		return ""
	}

	buf := make([]byte, int(usedBufLen))
	C.CFStringGetBytes(cr, rng, C.kCFStringEncodingUTF8, 0, 0, (*C.UInt8)(unsafe.Pointer(&buf[0])), C.CFIndex(len(buf)), &usedBufLen)

	sh := &reflect.StringHeader{
		Data: uintptr(unsafe.Pointer(&buf[0])),
		Len:  int(usedBufLen),
	}
	return *(*string)(unsafe.Pointer(sh))
}
Esempio n. 3
0
// 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])
}
Esempio n. 4
0
// cfstringGo creates a Go string for a CoreFoundation string using the CoreFoundation UTF-8 converter.
// For short strings this is an efficiency nightmare! In this package this function is not currently used
// in any critical path.
func cfstringGo(cfs C.CFStringRef) string {
	var usedBufLen C.CFIndex
	n := C.cfstring_utf8_length(cfs, &usedBufLen)
	if n <= 0 {
		return ""
	}
	rng := C.CFRange{location: C.CFIndex(0), length: n}
	buf := make([]byte, int(usedBufLen))

	bufp := unsafe.Pointer(&buf[0])
	C.CFStringGetBytes(cfs, rng, C.kCFStringEncodingUTF8, 0, 0, (*C.UInt8)(bufp), C.CFIndex(len(buf)), &usedBufLen)

	sh := &reflect.StringHeader{
		Data: uintptr(bufp),
		Len:  int(usedBufLen),
	}
	return *(*string)(unsafe.Pointer(sh))
}
Esempio n. 5
0
// 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])
}