apple: Start using some Cocoa APIs, clean up a few related things.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 08 Aug 2017 03:36:56 -0400
changeset 1549 59ee9cc813c8
parent 1548 576e95c756b5
child 1550 c849824939bd
apple: Start using some Cocoa APIs, clean up a few related things.
CMakeLists.txt
docs/INSTALL.txt
src/physfs_platform_apple.m
src/physfs_platforms.h
--- a/CMakeLists.txt	Tue Aug 08 02:34:25 2017 -0400
+++ b/CMakeLists.txt	Tue Aug 08 03:36:56 2017 -0400
@@ -25,7 +25,7 @@
 include_directories(./src)
 
 if(APPLE)
-    set(OTHER_LDFLAGS ${OTHER_LDFLAGS} "-framework CoreFoundation -framework IOKit")
+    set(OTHER_LDFLAGS ${OTHER_LDFLAGS} "-framework IOKit -framework Foundation")
     set(PHYSFS_M_SRCS src/physfs_platform_apple.m)
 endif()
 
--- a/docs/INSTALL.txt	Tue Aug 08 02:34:25 2017 -0400
+++ b/docs/INSTALL.txt	Tue Aug 08 03:36:56 2017 -0400
@@ -29,7 +29,9 @@
 enabled, needs no extra configuration, and allows static linking.
 WinRT and Haiku need C++ compilers for their system APIs, but if you aren't on
 these platforms and don't have a C++ compiler, don't build the .cpp files.
-Everything you need is in the .c sources.
+Likewise: Apple platforms (macOS, iOS, etc) need an Objective-C compiler, but
+if you aren't on these platforms and don't have a Objective-C compiler, don't
+build the .m file. Everything you need is in the .c sources.
 
 If this all worked for your specific project, you can stop reading now.
 
@@ -101,7 +103,6 @@
 correct OS version (8.0 or later).
 
 
-
 PocketPC/WindowsCE:
 
 Support for PocketPC was removed in PhysicsFS 2.1.0. This was known to work
--- a/src/physfs_platform_apple.m	Tue Aug 08 02:34:25 2017 -0400
+++ b/src/physfs_platform_apple.m	Tue Aug 08 03:36:56 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * macOS (iOS, etc) support routines for PhysicsFS.
+ * Apple platform (macOS, iOS, watchOS, etc) support routines for PhysicsFS.
  *
  * Please see the file LICENSE.txt in the source's root directory.
  *
@@ -9,17 +9,13 @@
 #define __PHYSICSFS_INTERNAL__
 #include "physfs_internal.h"
 
-#ifdef PHYSFS_PLATFORM_MACOS
-
-#include <CoreFoundation/CoreFoundation.h>
+#ifdef PHYSFS_PLATFORM_APPLE
 
-#if !defined(PHYSFS_NO_CDROM_SUPPORT)
-#include <IOKit/IOKitLib.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/storage/IOCDMedia.h>
-#include <IOKit/storage/IODVDMedia.h>
-#include <sys/mount.h>
-#endif
+/* Foundation.h steps on these. :( */
+#undef malloc
+#undef free
+
+#include <Foundation/Foundation.h>
 
 int __PHYSFS_platformInit(void)
 {
@@ -33,6 +29,41 @@
 } /* __PHYSFS_platformDeinit */
 
 
+char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+{
+    @autoreleasepool
+    {
+        NSString *path = [[NSBundle mainBundle] bundlePath];
+        BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL);
+        size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+        char *retval = (char *) allocator.Malloc(len + 2);
+        BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+        [path getCString:retval maxLength:len+1 encoding:NSUTF8StringEncoding];
+        retval[len] = '/';
+        retval[len+1] = '\0';
+        return retval;  /* whew. */
+    } /* @autoreleasepool */
+} /* __PHYSFS_platformCalcBaseDir */
+
+
+char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
+{
+    @autoreleasepool
+    {
+        NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, TRUE);
+        BAIL_IF(!paths, PHYSFS_ERR_OS_ERROR, NULL);
+        NSString *path = paths[0];
+        BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL);
+        size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+        const size_t applen = strlen(app);
+        char *retval = (char *) allocator.Malloc(len + applen + 3);
+        BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+        [path getCString:retval maxLength:len+1 encoding:NSUTF8StringEncoding];
+        snprintf(retval + len, applen + 3, "/%s/", app);
+        return retval;  /* whew. */
+    } /* @autoreleasepool */
+} /* __PHYSFS_platformCalcPrefDir */
+
 
 /* CD-ROM detection code... */
 
@@ -43,6 +74,12 @@
 
 #if !defined(PHYSFS_NO_CDROM_SUPPORT)
 
+#include <IOKit/IOKitLib.h>
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/storage/IOCDMedia.h>
+#include <IOKit/storage/IODVDMedia.h>
+#include <sys/mount.h>
+
 static int darwinIsWholeMedia(io_service_t service)
 {
     int retval = 0;
@@ -147,72 +184,7 @@
 #endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
 } /* __PHYSFS_platformDetectAvailableCDs */
 
-
-static char *convertCFString(CFStringRef cfstr)
-{
-    CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
-                                                    kCFStringEncodingUTF8) + 1;
-    char *retval = (char *) allocator.Malloc(len);
-    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
-
-    if (CFStringGetCString(cfstr, retval, len, kCFStringEncodingUTF8))
-    {
-        /* shrink overallocated buffer if possible... */
-        CFIndex newlen = strlen(retval) + 1;
-        if (newlen < len)
-        {
-            void *ptr = allocator.Realloc(retval, newlen);
-            if (ptr != NULL)
-                retval = (char *) ptr;
-        } /* if */
-    } /* if */
-
-    else  /* probably shouldn't fail, but just in case... */
-    {
-        allocator.Free(retval);
-        BAIL(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
-    } /* else */
-
-    return retval;
-} /* convertCFString */
-
+#endif /* PHYSFS_PLATFORM_APPLE */
 
-char *__PHYSFS_platformCalcBaseDir(const char *argv0)
-{
-    CFURLRef cfurl = NULL;
-    CFStringRef cfstr = NULL;
-    CFMutableStringRef cfmutstr = NULL;
-    char *retval = NULL;
-
-    cfurl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
-    BAIL_IF(cfurl == NULL, PHYSFS_ERR_OS_ERROR, NULL);
-    cfstr = CFURLCopyFileSystemPath(cfurl, kCFURLPOSIXPathStyle);
-    CFRelease(cfurl);
-    BAIL_IF(!cfstr, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
-    cfmutstr = CFStringCreateMutableCopy(NULL, 0, cfstr);
-    CFRelease(cfstr);
-    BAIL_IF(!cfmutstr, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
-    CFStringAppendCString(cfmutstr, "/", kCFStringEncodingUTF8);
-    retval = convertCFString(cfmutstr);
-    CFRelease(cfmutstr);
+/* end of physfs_platform_apple.m ... */
 
-    return retval;  /* whew. */
-} /* __PHYSFS_platformCalcBaseDir */
-
-
-char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
-{
-    /* !!! FIXME-3.0: there's a real API to determine this */
-    const char *userdir = __PHYSFS_getUserDir();
-    const char *append = "Library/Application Support/";
-    const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
-    char *retval = allocator.Malloc(len);
-    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
-    snprintf(retval, len, "%s%s%s/", userdir, append, app);
-    return retval;
-} /* __PHYSFS_platformCalcPrefDir */
-
-#endif /* PHYSFS_PLATFORM_MACOS */
-
-/* end of physfs_platform_macos.c ... */
-
--- a/src/physfs_platforms.h	Tue Aug 08 02:34:25 2017 -0400
+++ b/src/physfs_platforms.h	Tue Aug 08 03:36:56 2017 -0400
@@ -33,12 +33,12 @@
 #elif defined(__OS2__) || defined(OS2)
 #  define PHYSFS_PLATFORM_OS2 1
 #elif ((defined __MACH__) && (defined __APPLE__))
-/* To check if iphone or not, we need to include this file */
+/* To check if iOS or not, we need to include this file */
 #  include <TargetConditionals.h>
 #  if ((TARGET_IPHONE_SIMULATOR) || (TARGET_OS_IPHONE))
 #     define PHYSFS_NO_CDROM_SUPPORT 1
 #  endif
-#  define PHYSFS_PLATFORM_MACOS 1
+#  define PHYSFS_PLATFORM_APPLE 1
 #  define PHYSFS_PLATFORM_POSIX 1
 #elif defined(macintosh)
 #  error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.