Fix fopen() on windows to cope with long filenames (part of #1755).
[dcpomatic.git] / src / lib / cross_osx.cc
index 7817348e229566a91a06440774beb6bdab8d510a..bd31541c5e8b9a700d895f8bf54dde0270ba5ce6 100644 (file)
@@ -31,7 +31,6 @@ extern "C" {
 #include <libavformat/avio.h>
 }
 #include <boost/algorithm/string.hpp>
-#include <boost/foreach.hpp>
 #include <boost/regex.hpp>
 #if BOOST_VERSION >= 106100
 #include <boost/dll/runtime_symbol_info.hpp>
@@ -64,7 +63,7 @@ using std::cerr;
 using std::cout;
 using std::runtime_error;
 using std::map;
-using boost::shared_ptr;
+using std::shared_ptr;
 using boost::optional;
 using boost::function;
 
@@ -100,19 +99,7 @@ cpu_info ()
 boost::filesystem::path
 directory_containing_executable ()
 {
-#if BOOST_VERSION >= 106100
        return boost::dll::program_location().parent_path();
-#else
-       uint32_t size = 1024;
-       char buffer[size];
-       if (_NSGetExecutablePath (buffer, &size)) {
-               throw runtime_error ("_NSGetExecutablePath failed");
-       }
-
-       boost::filesystem::path path (buffer);
-       path = boost::filesystem::canonical (path);
-       return path.parent_path ();
-#endif
 }
 
 
@@ -209,9 +196,8 @@ void
 start_tool (string executable, string app)
 {
        boost::filesystem::path exe_path = directory_containing_executable();
-       exe_path = exe_path.parent_path (); // MacOS
        exe_path = exe_path.parent_path (); // Contents
-       exe_path = exe_path.parent_path (); // DCP-o-matic.app
+       exe_path = exe_path.parent_path (); // DCP-o-matic 2.app
        exe_path = exe_path.parent_path (); // Applications
        exe_path /= app;
        exe_path /= "Contents";
@@ -261,12 +247,6 @@ home_directory ()
                return getenv("HOME");
 }
 
-string
-command_and_read (string)
-{
-       return "";
-}
-
 /** @return true if this process is a 32-bit one running on a 64-bit-capable OS */
 bool
 running_32_on_64 ()
@@ -280,10 +260,15 @@ get_vendor (CFDictionaryRef& description)
 {
        void const* str = CFDictionaryGetValue (description, kDADiskDescriptionDeviceVendorKey);
        if (!str) {
-               return optional<string>();
+               return {};
+       }
+
+       auto c_str = CFStringGetCStringPtr ((CFStringRef) str, kCFStringEncodingUTF8);
+       if (!c_str) {
+               return {};
        }
 
-       string s = CFStringGetCStringPtr ((CFStringRef) str, kCFStringEncodingUTF8);
+       string s (c_str);
        boost::algorithm::trim (s);
        return s;
 }
@@ -293,10 +278,15 @@ get_model (CFDictionaryRef& description)
 {
        void const* str = CFDictionaryGetValue (description, kDADiskDescriptionDeviceModelKey);
        if (!str) {
-               return optional<string>();
+               return {};
        }
 
-       string s = CFStringGetCStringPtr ((CFStringRef) str, kCFStringEncodingUTF8);
+       auto c_str = CFStringGetCStringPtr ((CFStringRef) str, kCFStringEncodingUTF8);
+       if (!c_str) {
+               return {};
+       }
+
+       string s (c_str);
        boost::algorithm::trim (s);
        return s;
 }
@@ -314,17 +304,23 @@ analyse_media_path (CFDictionaryRef& description)
 
        void const* str = CFDictionaryGetValue (description, kDADiskDescriptionMediaPathKey);
        if (!str) {
-               LOG_DISK_NC("There is no MediaPathKey");
-               return optional<MediaPath>();
+               LOG_DISK_NC("There is no MediaPathKey (no dictionary value)");
+               return {};
+       }
+
+       auto path_key_cstr = CFStringGetCStringPtr((CFStringRef) str, kCFStringEncodingUTF8);
+       if (!path_key_cstr) {
+               LOG_DISK_NC("There is no MediaPathKey (no cstring)");
+               return {};
        }
 
-       string path(CFStringGetCStringPtr((CFStringRef) str, kCFStringEncodingUTF8));
+       string path(path_key_cstr);
        LOG_DISK("MediaPathKey is %1", path);
 
        if (path.find("/IOHDIXController") != string::npos) {
                /* This is a disk image, so we completely ignore it */
                LOG_DISK_NC("Ignoring this as it seems to be a disk image");
-               return optional<MediaPath>();
+               return {};
        }
 
        MediaPath mp;
@@ -333,12 +329,12 @@ analyse_media_path (CFDictionaryRef& description)
        } else if (starts_with(path, "IOService:")) {
                mp.real = false;
        } else {
-               return optional<MediaPath>();
+               return {};
        }
 
        vector<string> bits;
        split(bits, path, boost::is_any_of("/"));
-       BOOST_FOREACH (string i, bits) {
+       for (auto i: bits) {
                if (starts_with(i, "PRT")) {
                        mp.prt = i;
                }
@@ -364,10 +360,14 @@ is_whole_drive (DADiskRef& disk)
 static optional<boost::filesystem::path>
 mount_point (CFDictionaryRef& description)
 {
-       CFURLRef volume_path_key = (CFURLRef) CFDictionaryGetValue (description, kDADiskDescriptionVolumePathKey);
+       auto volume_path_key = (CFURLRef) CFDictionaryGetValue (description, kDADiskDescriptionVolumePathKey);
+       if (!volume_path_key) {
+               return {};
+       }
+
        char mount_path_buffer[1024];
        if (!CFURLGetFileSystemRepresentation(volume_path_key, false, (UInt8 *) mount_path_buffer, sizeof(mount_path_buffer))) {
-               return boost::optional<boost::filesystem::path>();
+               return {};
        }
        return boost::filesystem::path(mount_path_buffer);
 }
@@ -411,8 +411,9 @@ struct Disk
 static void
 disk_appeared (DADiskRef disk, void* context)
 {
-       const char* bsd_name = DADiskGetBSDName (disk);
+       auto bsd_name = DADiskGetBSDName (disk);
        if (!bsd_name) {
+               LOG_DISK_NC("Disk with no BSDName appeared");
                return;
        }
        LOG_DISK("%1 appeared", bsd_name);
@@ -420,6 +421,7 @@ disk_appeared (DADiskRef disk, void* context)
        Disk this_disk;
 
        this_disk.mount_point = string("/dev/") + bsd_name;
+       LOG_DISK("Mount point is %1", this_disk.mount_point);
 
        CFDictionaryRef description = DADiskCopyDescription (disk);
 
@@ -427,7 +429,7 @@ disk_appeared (DADiskRef disk, void* context)
        this_disk.model = get_model (description);
        LOG_DISK("Vendor/model: %1 %2", this_disk.vendor.get_value_or("[none]"), this_disk.model.get_value_or("[none]"));
 
-       optional<MediaPath> media_path = analyse_media_path (description);
+       auto media_path = analyse_media_path (description);
        if (!media_path) {
                LOG_DISK("Finding media path for %1 failed", bsd_name);
                return;
@@ -436,7 +438,7 @@ disk_appeared (DADiskRef disk, void* context)
        this_disk.real = media_path->real;
        this_disk.prt = media_path->prt;
        this_disk.whole = is_whole_drive (disk);
-       optional<boost::filesystem::path> mp = mount_point (description);
+       auto mp = mount_point (description);
        if (mp) {
                this_disk.mount_points.push_back (*mp);
        }
@@ -449,7 +451,13 @@ disk_appeared (DADiskRef disk, void* context)
                 mp ? ("mounted at " + mp->string()) : "unmounted"
                );
 
-       CFNumberGetValue ((CFNumberRef) CFDictionaryGetValue (description, kDADiskDescriptionMediaSizeKey), kCFNumberLongType, &this_disk.size);
+       auto media_size_cstr = CFDictionaryGetValue (description, kDADiskDescriptionMediaSizeKey);
+       if (!media_size_cstr) {
+               LOG_DISK_NC("Could not read media size");
+               return;
+       }
+
+       CFNumberGetValue ((CFNumberRef) media_size_cstr, kCFNumberLongType, &this_disk.size);
        CFRelease (description);
 
        reinterpret_cast<vector<Disk>*>(context)->push_back(this_disk);
@@ -463,7 +471,7 @@ Drive::get ()
 
        DASessionRef session = DASessionCreate(kCFAllocatorDefault);
        if (!session) {
-               return vector<Drive>();
+               return {};
        }
 
        DARegisterDiskAppearedCallback (session, NULL, disk_appeared, &disks);
@@ -475,11 +483,11 @@ Drive::get ()
        CFRelease(session);
 
        /* Mark disks containing mounted partitions as themselves mounted */
-       BOOST_FOREACH (Disk& i, disks) {
+       for (auto& i: disks) {
                if (!i.whole) {
                        continue;
                }
-               BOOST_FOREACH (Disk& j, disks) {
+               for (auto& j: disks) {
                        if (!j.mount_points.empty() && starts_with(j.mount_point, i.mount_point)) {
                                LOG_DISK("Marking %1 as mounted because %2 is", i.mount_point, j.mount_point);
                                std::copy(j.mount_points.begin(), j.mount_points.end(), back_inserter(i.mount_points));
@@ -489,7 +497,7 @@ Drive::get ()
 
        /* Make a map of the PRT codes and mount points of mounted, synthesized disks */
        map<string, vector<boost::filesystem::path> > mounted_synths;
-       BOOST_FOREACH (Disk& i, disks) {
+       for (auto& i: disks) {
                if (!i.real && !i.mount_points.empty()) {
                        LOG_DISK("Found a mounted synth %1 with %2", i.mount_point, i.prt);
                        mounted_synths[i.prt] = i.mount_points;
@@ -497,9 +505,9 @@ Drive::get ()
        }
 
        /* Mark containers of those mounted synths as themselves mounted */
-       BOOST_FOREACH (Disk& i, disks) {
+       for (auto& i: disks) {
                if (i.real) {
-                       map<string, vector<boost::filesystem::path> >::const_iterator j = mounted_synths.find(i.prt);
+                       auto j = mounted_synths.find(i.prt);
                        if (j != mounted_synths.end()) {
                                LOG_DISK("Marking %1 (%2) as mounted because it contains a mounted synth", i.mount_point, i.prt);
                                std::copy(j->second.begin(), j->second.end(), back_inserter(i.mount_points));
@@ -508,7 +516,7 @@ Drive::get ()
        }
 
        vector<Drive> drives;
-       BOOST_FOREACH (Disk& i, disks) {
+       for (auto& i: disks) {
                if (i.whole) {
                        /* A whole disk that is not a container for a mounted synth */
                        drives.push_back(Drive(i.mount_point, i.mount_points, i.size, i.vendor, i.model));
@@ -593,3 +601,16 @@ DCPOMATIC_ENABLE_WARNINGS
        TransformProcessType (&serial, kProcessTransformToForegroundApplication);
 }
 
+
+string
+dcpomatic::get_process_id ()
+{
+       return dcp::raw_convert<string>(getpid());
+}
+
+
+boost::filesystem::path
+fix_long_path (boost::filesystem::path path)
+{
+       return path;
+}