diff dep/animia/src/util/osx.cc @ 169:e44b7c428d7c

dep/animia: add libkvm method (UNTESTED)
author Paper <mrpapersonic@gmail.com>
date Sun, 19 Nov 2023 17:30:38 -0500
parents 8937fb7f2d66
children c413e475f496
line wrap: on
line diff
--- a/dep/animia/src/util/osx.cc	Sun Nov 19 05:36:41 2023 -0500
+++ b/dep/animia/src/util/osx.cc	Sun Nov 19 17:30:38 2023 -0500
@@ -1,5 +1,8 @@
 #include "animia/util/osx.h"
 
+#include <string>
+#include <memory>
+
 #ifdef HAVE_COREFOUNDATION
 #include <CoreFoundation/CoreFoundation.h>
 #endif
@@ -7,12 +10,20 @@
 namespace animia::internal::osx::util {
 
 #ifdef HAVE_COREFOUNDATION
-/* All of these LaunchServices things use *internal functions* that are subject
-** to change. Granted, it's not very likely that these will change very much
-** because I'm fairly sure Apple uses them lots in their own internal code.
+/* I don't want to have to call CFRelease */
+template<typename T>
+struct CFDeleter {
+	using pointer = T;
+	void operator()(pointer p) { CFRelease(p); }
+}
+
+template<typename T>
+typedef CFReference = std::unique_ptr<T, CFDeleter>;
+
+/* all of these LaunchServices things use *internal functions* that are subject
+ * to change. Granted, it's not very likely that these will change very much
+ * because I'm fairly sure Apple uses them lots in their own internal code.
 */
-
-/* from RDProcess */
 typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t);
 typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef);
 
@@ -21,6 +32,7 @@
 
 /* retrieved from LaunchServicesSPI.h in WebKit */
 static constexpr int kLSDefaultSessionID = -2;
+
 static const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.LaunchServices");
 
 /* retrieved dynamically */
@@ -56,33 +68,26 @@
 		if (!GetLaunchServicesPrivateSymbols())
 			return false;
 
-	CFTypeRef asn = LSASNCreateWithPid(kCFAllocatorDefault, pid);
-
-	CFArrayRef request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL);
+	CFReference<CFTypeRef> asn = LSASNCreateWithPid(kCFAllocatorDefault, pid);
 
-	CFDictionaryRef dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array);
+	CFReference<CFArrayRef> request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL);
 
-	CFRelease(request_array);
-	if (!dictionary)
+	CFReference<CFDictionaryRef> dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array.get());
+	if (!dictionary.get())
 		return false;
 
-	CFStringRef str;
-	if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&str) || !str) {
-		CFRelease(dictionary);
-		return false;
-	}
-	CFRetain(str);
-
-	CFRelease(dictionary);
-
-	result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1);
-
-	if (!CFStringGetCString(str, &result.front(), result.length(), result.length())) {
-		CFRelease(str);
-		return false;
+	CFReference<CFStringRef> str;
+	{
+		CFStringRef rstr;
+		if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&rstr) || !rstr)
+			return false;
+		str.reset(rstr);
 	}
 
-	CFRelease(str);
+	result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str.get()), kCFStringEncodingUTF8) + 1);
+
+	if (!CFStringGetCString(str.get(), &result.front(), result.length(), result.length()))
+		return false;
 
 	return true;
 }