libobs: Add CFString utils

This commit is contained in:
Marvin Scholz 2018-09-16 17:52:41 +02:00
parent c7dab6c92b
commit 31f143e449
3 changed files with 110 additions and 2 deletions

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,7 @@
/*
* Copyright (c) 2013-2014 Ruwen Hahn <palana@stunned.de>
* Copyright (c) 2013-2018 Ruwen Hahn <palana@stunned.de>
* Hugh "Jim" Bailey <obs.jim@gmail.com>
* Marvin Scholz <epirat07@gmail.com>
*
* 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;
}