Skip to content
This repository
Browse code

[OSX] Remove all direct calls to CFStringGetCString and CFStringGetCS…

…tringPtr

This adds a new util function DarwinCFStringToString that handles errors
and tries to first get the pointer otherwise copies the string into a
std::string. It also makes sure to use CFStringGetSystemEncoding()
everywhere so we don't get in trouble for using a hardcoded encoding.
  • Loading branch information...
commit 4b4bb2768450367c9aee1066bacf4f428f31fe5a 1 parent 2a07283
Tobias Hieta authored January 16, 2013
6  xbmc/cores/AudioEngine/Engines/CoreAudio/CoreAudioHardware.cpp
@@ -22,6 +22,7 @@
22 22
 
23 23
 #include "CoreAudioAEHAL.h"
24 24
 #include "utils/log.h"
  25
+#include "osx/DarwinUtils.h"
25 26
 
26 27
 bool CCoreAudioHardware::GetAutoHogMode()
27 28
 {
@@ -329,9 +330,8 @@ void CCoreAudioHardware::GetOutputDeviceName(std::string& name)
329 330
     if (ret != noErr)
330 331
       return;
331 332
 
332  
-    const char *cstr = CFStringGetCStringPtr(theDeviceName, CFStringGetSystemEncoding());
333  
-    if (cstr)
334  
-      name = cstr;
  333
+    DarwinCFStringRefToString(theDeviceName, name);
  334
+
335 335
     CFRelease(theDeviceName);
336 336
   }
337 337
 }
54  xbmc/network/osx/ZeroconfBrowserOSX.cpp
@@ -26,33 +26,13 @@
26 26
 #include "guilib/GUIMessage.h"
27 27
 #include "threads/SingleLock.h"
28 28
 #include "utils/log.h"
  29
+#include "osx/DarwinUtils.h"
29 30
 
30 31
 #include <arpa/inet.h>
31 32
 #include <netinet/in.h>
32 33
 
33 34
 namespace
34 35
 {
35  
-  CStdString CFStringToCStdString(const CFStringRef cfstr)
36  
-  {
37  
-    //first try the short path
38  
-    const char *p_tmp = CFStringGetCStringPtr(cfstr, kCFStringEncodingUTF8);
39  
-    if (p_tmp)
40  
-      return CStdString(p_tmp);
41  
-    
42  
-    // i'm not sure if CFStringGetMaximumSizeForEncoding
43  
-    // includes space for the termination character or not?
44  
-    // so i add 1 here to make sure..
45  
-    CFIndex buf_len = 1 + CFStringGetMaximumSizeForEncoding(
46  
-      CFStringGetLength(cfstr), kCFStringEncodingUTF8);
47  
-
48  
-    char *buffer = new char[buf_len];
49  
-    CFStringGetCString(cfstr, buffer, buf_len, kCFStringEncodingUTF8);
50  
-    CStdString myString(buffer);
51  
-    delete[] buffer;
52  
-
53  
-    return myString;
54  
-  }
55  
-  
56 36
   //helper for getting a the txt-records list
57 37
   //returns true on success, false if nothing found or error
58 38
   CZeroconfBrowser::ZeroconfService::tTxtRecordMap GetTxtRecords(CFNetServiceRef serviceRef)  
@@ -78,12 +58,16 @@ namespace
78 58
 
79 59
           for(idx = 0; idx < numValues; idx++)
80 60
           {
81  
-            recordMap.insert(
82  
-              std::make_pair(
83  
-                CFStringToCStdString(keys[idx]),
84  
-                CStdString((const char *)CFDataGetBytePtr(values[idx]))
85  
-              )
86  
-            );
  61
+            std::string key;
  62
+            if (DarwinCFStringRefToString(keys[idx], key))
  63
+            {
  64
+              recordMap.insert(
  65
+                std::make_pair(
  66
+                  key,
  67
+                  CStdString((const char *)CFDataGetBytePtr(values[idx]))
  68
+                )
  69
+              );
  70
+            }
87 71
           }
88 72
         }
89 73
         CFRelease(dict);
@@ -161,11 +145,19 @@ void CZeroconfBrowserOSX::BrowserCallback(CFNetServiceBrowserRef browser, CFOpti
161 145
     assert(service);
162 146
     //get our instance
163 147
     CZeroconfBrowserOSX* p_this = reinterpret_cast<CZeroconfBrowserOSX*>(info);
  148
+
164 149
     //store the service
165  
-    ZeroconfService s(
166  
-      CFStringToCStdString(CFNetServiceGetName(service)),
167  
-      CFStringToCStdString(CFNetServiceGetType(service)),
168  
-      CFStringToCStdString(CFNetServiceGetDomain(service)));
  150
+    std::string name, type, domain;
  151
+    if (!DarwinCFStringRefToString(CFNetServiceGetName(service), name) ||
  152
+        !DarwinCFStringRefToString(CFNetServiceGetType(service), type) ||
  153
+        !DarwinCFStringRefToString(CFNetServiceGetDomain(service), domain))
  154
+    {
  155
+      CLog::Log(LOGWARNING, "CZeroconfBrowserOSX::BrowserCallback failed to convert service strings.");
  156
+      return;
  157
+    }
  158
+
  159
+    ZeroconfService s(name, type, domain);
  160
+
169 161
     if (flags & kCFNetServiceFlagRemove)
170 162
     {
171 163
       CLog::Log(LOGDEBUG, "CZeroconfBrowserOSX::BrowserCallback service named: %s, type: %s, domain: %s disappeared", 
6  xbmc/osx/DarwinUtils.h
@@ -22,6 +22,11 @@
22 22
 
23 23
 #include <string>
24 24
 
  25
+// We forward declare CFStringRef in order to avoid
  26
+// pulling in tons of Objective-C headers.
  27
+struct __CFString;
  28
+typedef const struct __CFString * CFStringRef;
  29
+
25 30
 #ifdef __cplusplus
26 31
 extern "C"
27 32
 {
@@ -35,6 +40,7 @@ extern "C"
35 40
   bool        DarwinHasVideoToolboxDecoder(void);
36 41
   int         DarwinBatteryLevel(void);
37 42
   void        DarwinSetScheduling(int message);
  43
+  bool        DarwinCFStringRefToString(CFStringRef source, std::string& destination);
38 44
 #ifdef __cplusplus
39 45
 }
40 46
 #endif
29  xbmc/osx/DarwinUtils.mm
@@ -35,6 +35,7 @@
35 35
   #import <sys/sysctl.h>
36 36
 #else
37 37
   #import <Cocoa/Cocoa.h>
  38
+  #import <CoreFoundation/CoreFoundation.h>
38 39
   #import <IOKit/ps/IOPowerSources.h>
39 40
   #import <IOKit/ps/IOPSKeys.h>
40 41
 #endif
@@ -316,4 +317,32 @@ void DarwinSetScheduling(int message)
316 317
   result = pthread_setschedparam(this_pthread_self, policy, &param );
317 318
 }
318 319
 
  320
+bool DarwinCFStringRefToString(CFStringRef source, std::string &destination)
  321
+{
  322
+  const char *cstr = CFStringGetCStringPtr(source, CFStringGetSystemEncoding());
  323
+  if (!cstr)
  324
+  {
  325
+    CFIndex strLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(source) + 1,
  326
+                                                       CFStringGetSystemEncoding());
  327
+    char *allocStr = (char*)malloc(strLen);
  328
+
  329
+    if(!allocStr)
  330
+      return false;
  331
+
  332
+    if(!CFStringGetCString(source, allocStr, strLen, CFStringGetSystemEncoding()))
  333
+    {
  334
+      free((void*)allocStr);
  335
+      return false;
  336
+    }
  337
+
  338
+    destination = allocStr;
  339
+    free((void*)allocStr);
  340
+
  341
+    return true;
  342
+  }
  343
+
  344
+  destination = cstr;
  345
+  return true;
  346
+}
  347
+
319 348
 #endif
13  xbmc/peripherals/bus/osx/PeripheralBusUSB.cpp
@@ -21,6 +21,7 @@
21 21
 #include "PeripheralBusUSB.h"
22 22
 #include "peripherals/Peripherals.h"
23 23
 #include "utils/log.h"
  24
+#include "osx/DarwinUtils.h"
24 25
 
25 26
 #include <sys/param.h>
26 27
 
@@ -224,7 +225,7 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera
224 225
       result = (*interfaceInterface)->GetInterfaceClass(interfaceInterface, &bInterfaceClass);
225 226
       if (bInterfaceClass == kUSBHIDInterfaceClass || bInterfaceClass == kUSBCommunicationDataInterfaceClass)
226 227
       {
227  
-        char ttlDeviceFilePath[MAXPATHLEN] = {0};
  228
+        std::string ttlDeviceFilePath;
228 229
         CFStringRef deviceFilePathAsCFString;
229 230
         USBDevicePrivateData *privateDataRef;
230 231
         privateDataRef = new USBDevicePrivateData;
@@ -248,16 +249,16 @@ void CPeripheralBusUSB::DeviceAttachCallback(CPeripheralBusUSB* refCon, io_itera
248 249
               kIOServicePlane, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, kIORegistryIterateRecursively);
249 250
             if (deviceFilePathAsCFString)
250 251
             {
251  
-              // Convert the path from a CFString to a NULL-terminated C string
252  
-              CFStringGetCString((CFStringRef)deviceFilePathAsCFString,
253  
-                ttlDeviceFilePath, MAXPATHLEN - 1, kCFStringEncodingASCII);
  252
+              // Convert the path from a CFString to a std::string
  253
+              if (!DarwinCFStringRefToString(deviceFilePathAsCFString, ttlDeviceFilePath))
  254
+                CLog::Log(LOGWARNING, "CPeripheralBusUSB::DeviceAttachCallback failed to convert CFStringRef");
254 255
               CFRelease(deviceFilePathAsCFString);
255 256
             }
256 257
             IOObjectRelease(parent);
257 258
           }
258 259
         }
259  
-        if (strlen(ttlDeviceFilePath))
260  
-          privateDataRef->result.m_strLocation.Format("%s", ttlDeviceFilePath);
  260
+        if (!ttlDeviceFilePath.empty())
  261
+          privateDataRef->result.m_strLocation.Format("%s", ttlDeviceFilePath.c_str());
261 262
         else
262 263
           privateDataRef->result.m_strLocation.Format("%d", locationId);
263 264
 
6  xbmc/windowing/osx/WinSystemOSX.mm
@@ -36,6 +36,7 @@
36 36
 #include "osx/XBMCHelper.h"
37 37
 #include "utils/SystemInfo.h"
38 38
 #include "osx/CocoaInterface.h"
  39
+#include "osx/DarwinUtils.h"
39 40
 #undef BOOL
40 41
 
41 42
 #import <SDL/SDL_video.h>
@@ -1358,8 +1359,9 @@ static void DisplayReconfigured(CGDirectDisplayID display,
1358 1359
         // if the windowBounds completely encloses our bounds, we are obscured.
1359 1360
         if (!obscureLogged)
1360 1361
         {
1361  
-          const char* cstr = CFStringGetCStringPtr(ownerName, CFStringGetSystemEncoding());
1362  
-          CLog::Log(LOGDEBUG, "WinSystemOSX: Fullscreen window %s obscures XBMC!", cstr);
  1362
+          std::string appName;
  1363
+          if (DarwinCFStringRefToString(ownerName, appName))
  1364
+            CLog::Log(LOGDEBUG, "WinSystemOSX: Fullscreen window %s obscures XBMC!", appName.c_str());
1363 1365
           obscureLogged = true;
1364 1366
         }
1365 1367
         m_obscured = true;

0 notes on commit 4b4bb27

Please sign in to comment.
Something went wrong with that request. Please try again.