Skip to content

Instantly share code, notes, and snippets.

@groob
Created November 8, 2016 22:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save groob/34da9aa005dfc5a3360f65744ae52861 to your computer and use it in GitHub Desktop.
Save groob/34da9aa005dfc5a3360f65744ae52861 to your computer and use it in GitHub Desktop.
read safari homepage in go
package main
/*
#cgo LDFLAGS: -framework IOKit -framework ApplicationServices
#include <CoreFoundation/CoreFoundation.h>
#include <stdlib.h>
// cfstring_utf8_length returns the number of characters successfully converted to UTF-8 and
// the bytes required to store them.
static inline CFIndex cfstring_utf8_length(CFStringRef str, CFIndex *need) {
CFIndex n, usedBufLen;
CFRange rng = CFRangeMake(0, CFStringGetLength(str));
return CFStringGetBytes(str, rng, kCFStringEncodingUTF8, 0, 0, NULL, 0, need);
}
*/
import "C"
import (
"fmt"
"reflect"
"unsafe"
)
// 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))
}
// cfstring efficiently creates a CFString from a Go String.
func cfstring(s string) C.CFStringRef {
n := C.CFIndex(len(s))
return C.CFStringCreateWithBytes(nil, *(**C.UInt8)(unsafe.Pointer(&s)), n, C.kCFStringEncodingUTF8, 0)
}
func main() {
hp := cfstring("HomePage")
saf := cfstring("com.Apple.Safari")
cs := C.CFPreferencesCopyAppValue(hp, saf)
if cs == nil {
return
}
fmt.Printf("%#v\n", cfstringGo(C.CFStringRef(cs)))
}
@noelmom
Copy link

noelmom commented Jun 30, 2020

I'm looking for something like this but can't get it to work. Getting an error:

package main: /Users/myuser/go/src/github.com/myuser/go_CFPreferencesCopyAppValue/main.go: invalid #cgo verb: #cgo LDFLGS: -framework IOKit -framework ApplicationServices

Any ideas?

@groob
Copy link
Author

groob commented Jun 30, 2020

@noelmom
Copy link

noelmom commented Jun 30, 2020

Thanks! I'll check it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment