github.com/Code-Hex/battery@v1.0.0/internal/macos/corefoundation.go (about) 1 //go:build darwin 2 3 package macOS 4 5 import ( 6 "errors" 7 "reflect" 8 "runtime" 9 "unsafe" 10 ) 11 12 // Core Foundation linker flags for the external linker. See Issue 42459 in golang/go. 13 14 // CFRef is an opaque reference to a Core Foundation object. It is a pointer, 15 // but to memory not owned by Go, so not an unsafe.Pointer. 16 type CFRef uintptr 17 18 // syscall is implemented in the runtime package (runtime/sys_darwin.go) 19 20 //go:linkname syscall crypto/x509/internal/macos.syscall 21 func syscall(fn, a1, a2, a3, a4, a5 uintptr, f1 float64) uintptr 22 23 // CFStringToString returns a Go string representation of the passed 24 // in CFString, or an empty string if it's invalid. 25 func CFStringToString(ref CFRef) string { 26 data, err := CFStringCreateExternalRepresentation(ref) 27 if err != nil { 28 return "" 29 } 30 b := CFDataToSlice(data) 31 CFRelease(data) 32 return string(b) 33 } 34 35 const kCFNumberIntType = 9 36 37 type CFString CFRef 38 39 const kCFAllocatorDefault = 0 40 const kCFStringEncodingUTF8 = 0x08000100 41 42 //go:cgo_import_dynamic battery_CFStringCreateExternalRepresentation CFStringCreateExternalRepresentation "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 43 44 func CFStringCreateExternalRepresentation(strRef CFRef) (CFRef, error) { 45 ret := syscall(FuncPC(battery_CFStringCreateExternalRepresentation_trampoline), kCFAllocatorDefault, uintptr(strRef), kCFStringEncodingUTF8, 0, 0, 0) 46 if ret == 0 { 47 return 0, errors.New("string can't be represented as UTF-8") 48 } 49 return CFRef(ret), nil 50 } 51 func battery_CFStringCreateExternalRepresentation_trampoline() 52 53 func CFDataToSlice(data CFRef) []byte { 54 length := CFDataGetLength(data) 55 ptr := CFDataGetBytePtr(data) 56 src := (*[1 << 20]byte)(unsafe.Pointer(ptr))[:length:length] 57 out := make([]byte, length) 58 copy(out, src) 59 return out 60 } 61 62 //go:cgo_import_dynamic battery_CFDataGetLength CFDataGetLength "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 63 64 func CFDataGetLength(data CFRef) int { 65 ret := syscall(FuncPC(battery_CFDataGetLength_trampoline), uintptr(data), 0, 0, 0, 0, 0) 66 return int(ret) 67 } 68 func battery_CFDataGetLength_trampoline() 69 70 //go:cgo_import_dynamic battery_CFDataGetBytePtr CFDataGetBytePtr "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 71 72 func CFDataGetBytePtr(data CFRef) uintptr { 73 ret := syscall(FuncPC(battery_CFDataGetBytePtr_trampoline), uintptr(data), 0, 0, 0, 0, 0) 74 return ret 75 } 76 func battery_CFDataGetBytePtr_trampoline() 77 78 //go:cgo_import_dynamic battery_CFRelease CFRelease "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 79 80 func CFRelease(ref CFRef) { 81 syscall(FuncPC(battery_CFRelease_trampoline), uintptr(ref), 0, 0, 0, 0, 0) 82 } 83 func battery_CFRelease_trampoline() 84 85 //go:cgo_import_dynamic battery_CFArrayGetCount CFArrayGetCount "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 86 87 func CFArrayGetCount(array CFRef) int { 88 ret := syscall(FuncPC(battery_CFArrayGetCount_trampoline), uintptr(array), 0, 0, 0, 0, 0) 89 return int(ret) 90 } 91 func battery_CFArrayGetCount_trampoline() 92 93 const kCFNumberSInt32Type = 3 94 95 //go:cgo_import_dynamic battery_CFNumberGetValue CFNumberGetValue "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 96 97 func CFNumberGetValue(num CFRef) (int32, error) { 98 var value int32 99 ret := syscall(FuncPC(battery_CFNumberGetValue_trampoline), uintptr(num), uintptr(kCFNumberSInt32Type), 100 uintptr(unsafe.Pointer(&value)), 0, 0, 0) 101 if ret == 0 { 102 return 0, errors.New("CFNumberGetValue call failed") 103 } 104 return value, nil 105 } 106 func battery_CFNumberGetValue_trampoline() 107 108 //go:cgo_import_dynamic battery_CFDictionaryGetValueIfPresent CFDictionaryGetValueIfPresent "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 109 110 func CFDictionaryGetValueIfPresent(dict CFRef, key CFString) (value CFRef, ok bool) { 111 ret := syscall(FuncPC(battery_CFDictionaryGetValueIfPresent_trampoline), uintptr(dict), uintptr(key), 112 uintptr(unsafe.Pointer(&value)), 0, 0, 0) 113 if ret == 0 { 114 return 0, false 115 } 116 return value, true 117 } 118 func battery_CFDictionaryGetValueIfPresent_trampoline() 119 120 //go:cgo_import_dynamic battery_CFStringCreateWithBytes CFStringCreateWithBytes "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 121 122 // StringToCFString returns a copy of the UTF-8 contents of s as a new CFString. 123 func StringToCFString(s string) CFString { 124 p := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data) 125 ret := syscall(FuncPC(battery_CFStringCreateWithBytes_trampoline), kCFAllocatorDefault, uintptr(p), 126 uintptr(len(s)), uintptr(kCFStringEncodingUTF8), 0 /* isExternalRepresentation */, 0) 127 runtime.KeepAlive(p) 128 return CFString(ret) 129 } 130 func battery_CFStringCreateWithBytes_trampoline() 131 132 //go:cgo_import_dynamic battery_CFArrayGetValueAtIndex CFArrayGetValueAtIndex "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" 133 134 func CFArrayGetValueAtIndex(array CFRef, index int) CFRef { 135 ret := syscall(FuncPC(battery_CFArrayGetValueAtIndex_trampoline), uintptr(array), uintptr(index), 0, 0, 0, 0) 136 return CFRef(ret) 137 } 138 func battery_CFArrayGetValueAtIndex_trampoline() 139 140 // ReleaseCFArray iterates through an array, releasing its contents, and then 141 // releases the array itself. This is necessary because we cannot, easily, set the 142 // CFArrayCallBacks argument when creating CFArrays. 143 func ReleaseCFArray(array CFRef) { 144 for i := 0; i < CFArrayGetCount(array); i++ { 145 ref := CFArrayGetValueAtIndex(array, i) 146 CFRelease(ref) 147 } 148 CFRelease(array) 149 }