Selaa lähdekoodia

libobs: Add CFString utils

Marvin Scholz 7 vuotta sitten
vanhempi
sitoutus
31f143e449
3 muutettua tiedostoa jossa 110 lisäystä ja 2 poistoa
  1. 2 1
      libobs/CMakeLists.txt
  2. 17 0
      libobs/util/apple/cfstring-utils.h
  3. 91 1
      libobs/util/platform-cocoa.m

+ 2 - 1
libobs/CMakeLists.txt

@@ -116,7 +116,8 @@ elseif(APPLE)
 		util/platform-nix.c
 		util/platform-cocoa.m)
 	set(libobs_PLATFORM_HEADERS
-		util/threading-posix.h)
+		util/threading-posix.h
+		util/apple/cfstring-utils.h)
 	set(libobs_audio_monitoring_SOURCES
 		audio-monitoring/osx/coreaudio-enum-devices.c
 		audio-monitoring/osx/coreaudio-output.c

+ 17 - 0
libobs/util/apple/cfstring-utils.h

@@ -0,0 +1,17 @@
+#pragma once
+
+#include "../c99defs.h"
+#include "../dstr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EXPORT char *cfstr_copy_cstr(CFStringRef cfstr, CFStringEncoding cfstr_enc);
+
+EXPORT bool cfstr_copy_dstr(CFStringRef cfstr, CFStringEncoding cfstr_enc, 
+		struct dstr *str);
+
+#ifdef __cplusplus
+}
+#endif

+ 91 - 1
libobs/util/platform-cocoa.m

@@ -1,6 +1,7 @@
 /*
- * Copyright (c) 2013-2014 Ruwen Hahn <[email protected]>
+ * Copyright (c) 2013-2018 Ruwen Hahn <[email protected]>
  *                         Hugh "Jim" Bailey <[email protected]>
+ *                         Marvin Scholz <[email protected]>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -33,6 +34,8 @@
 
 #import <Cocoa/Cocoa.h>
 
+#include "apple/cfstring-utils.h"
+
 /* clock function selection taken from libc++ */
 static uint64_t ns_time_simple()
 {
@@ -417,3 +420,90 @@ uint64_t os_get_proc_virtual_size(void)
 		return 0;
 	return taskinfo.virtual_size;
 }
+
+/* Obtains a copy of the contents of a CFString in specified encoding.
+ * Returns char* (must be bfree'd by caller) or NULL on failure.
+ */
+char *cfstr_copy_cstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding)
+{
+	if (!cfstring)
+		return NULL;
+
+	// Try the quick way to obtain the buffer
+	const char *tmp_buffer = CFStringGetCStringPtr(cfstring,
+			cfstring_encoding);
+
+	if (tmp_buffer != NULL)
+		return bstrdup(tmp_buffer);
+
+	// The quick way did not work, try the more expensive one
+	CFIndex length = CFStringGetLength(cfstring);
+	CFIndex max_size =
+		CFStringGetMaximumSizeForEncoding(length, cfstring_encoding);
+
+	// If result would exceed LONG_MAX, kCFNotFound is returned
+	if (max_size == kCFNotFound)
+		return NULL;
+
+	// Account for the null terminator
+	max_size++;
+
+	char *buffer = bmalloc(max_size);
+
+	if (buffer == NULL) {
+		return NULL;
+	}
+
+	// Copy CFString in requested encoding to buffer
+	Boolean success =
+		CFStringGetCString(cfstring, buffer, max_size, cfstring_encoding);
+
+	if (!success) {
+		bfree(buffer);
+		buffer = NULL;
+	}
+	return buffer;
+}
+
+/* Copies the contents of a CFString in specified encoding to a given dstr.
+ * Returns true on success or false on failure.
+ * In case of failure, the dstr capacity but not size is changed.
+ */
+bool cfstr_copy_dstr(CFStringRef cfstring,
+	CFStringEncoding cfstring_encoding, struct dstr *str)
+{
+	if (!cfstring)
+		return false;
+
+	// Try the quick way to obtain the buffer
+	const char *tmp_buffer = CFStringGetCStringPtr(cfstring,
+			cfstring_encoding);
+
+	if (tmp_buffer != NULL) {
+		dstr_copy(str, tmp_buffer);
+		return true;
+	}
+
+	// The quick way did not work, try the more expensive one
+	CFIndex length = CFStringGetLength(cfstring);
+	CFIndex max_size =
+		CFStringGetMaximumSizeForEncoding(length, cfstring_encoding);
+
+	// If result would exceed LONG_MAX, kCFNotFound is returned
+	if (max_size == kCFNotFound)
+		return NULL;
+
+	// Account for the null terminator
+	max_size++;
+
+	dstr_ensure_capacity(str, max_size);
+
+	// Copy CFString in requested encoding to dstr buffer
+	Boolean success = CFStringGetCString(
+		cfstring, str->array, max_size, cfstring_encoding);
+
+	if (success)
+		dstr_resize(str, max_size);
+
+	return (bool)success;
+}