From 233b0b87a0fee4f489be578231b9657c6e65bd82 Mon Sep 17 00:00:00 2001 From: Marvin Scholz Date: Mon, 8 Oct 2018 10:51:33 +0200 Subject: [PATCH] include/vlc_charset: Add FromCFString for darwin This is a helper function to obtain the copy of a char* from a CFStringRef. Changes compared to master: - Include CFString.h instead of the umbrella header to prevent a type clash with guid_t declared in the CoreFoundation headers. (cherry picked from commit f4b57268547f27172966cc7d850f797acaaa77d3) Signed-off-by: Marvin Scholz --- include/vlc_charset.h | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/include/vlc_charset.h b/include/vlc_charset.h index ca626b30b1..c77f198920 100644 --- a/include/vlc_charset.h +++ b/include/vlc_charset.h @@ -124,6 +124,50 @@ VLC_API char * vlc_strcasestr(const char *, const char *) VLC_USED; VLC_API char * FromCharset( const char *charset, const void *data, size_t data_size ) VLC_USED; VLC_API void * ToCharset( const char *charset, const char *in, size_t *outsize ) VLC_USED; +#ifdef __APPLE__ +# include + +/* Obtains a copy of the contents of a CFString in specified encoding. + * Returns char* (must be freed by caller) or NULL on failure. + */ +VLC_USED static inline char *FromCFString(const CFStringRef cfString, + const CFStringEncoding cfStringEncoding) +{ + // Try the quick way to obtain the buffer + const char *tmpBuffer = CFStringGetCStringPtr(cfString, cfStringEncoding); + + if (tmpBuffer != NULL) { + return strdup(tmpBuffer); + } + + // The quick way did not work, try the long way + CFIndex length = CFStringGetLength(cfString); + CFIndex maxSize = + CFStringGetMaximumSizeForEncoding(length, cfStringEncoding); + + // If result would exceed LONG_MAX, kCFNotFound is returned + if (unlikely(maxSize == kCFNotFound)) { + return NULL; + } + + // Account for the null terminator + maxSize++; + + char *buffer = (char *)malloc(maxSize); + + if (unlikely(buffer == NULL)) { + return NULL; + } + + // Copy CFString in requested encoding to buffer + Boolean success = CFStringGetCString(cfString, buffer, maxSize, cfStringEncoding); + + if (!success) + FREENULL(buffer); + return buffer; +} +#endif + #ifdef _WIN32 VLC_USED static inline char *FromWide (const wchar_t *wide)