X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Flib%2Fcross_common.cc;h=e8c209b21e098f8da981bd5676af55c0c00b65ab;hp=17546f712b97df87dd08f4474edb1980a35a1c3b;hb=c103d8c1306e5fb3937b3a6c430a3fff32653fa3;hpb=a3c73134fad8a4261c7cd655ae7531b347a78ac7 diff --git a/src/lib/cross_common.cc b/src/lib/cross_common.cc index 17546f712..e8c209b21 100644 --- a/src/lib/cross_common.cc +++ b/src/lib/cross_common.cc @@ -21,23 +21,28 @@ #include "cross.h" #include "compose.hpp" +#include "dcpomatic_assert.h" #include "dcpomatic_log.h" -#include "warnings.h" #include -DCPOMATIC_DISABLE_WARNINGS +#include +LIBDCP_DISABLE_WARNINGS #include -DCPOMATIC_ENABLE_WARNINGS +LIBDCP_ENABLE_WARNINGS #include #include #include "i18n.h" +using std::map; using std::string; using std::vector; using boost::optional; +auto constexpr MEDIA_PATH_REQUIRED_MATCHES = 3; + + Drive::Drive (string xml) { cxml::Document doc; @@ -123,8 +128,6 @@ Drive::log_summary () const optional analyse_osx_media_path (string path) { - using namespace boost::algorithm; - 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"); @@ -132,23 +135,84 @@ analyse_osx_media_path (string path) } OSXMediaPath mp; - if (starts_with(path, "IODeviceTree:")) { + vector parts; + split(parts, path, boost::is_any_of("/")); + std::copy(parts.begin() + 1, parts.end(), back_inserter(mp.parts)); + + if (!parts.empty() && parts[0] == "IODeviceTree:") { mp.real = true; - } else if (starts_with(path, "IOService:")) { + if (mp.parts.size() < MEDIA_PATH_REQUIRED_MATCHES) { + /* Later we expect at least MEDIA_PATH_REQUIRED_MATCHES parts in a IODeviceTree */ + LOG_DISK_NC("Ignoring this as it has a strange media path"); + return {}; + } + } else if (!parts.empty() && parts[0] == "IOService:") { mp.real = false; } else { return {}; } - vector bits; - split(bits, path, boost::is_any_of("/")); - for (auto i: bits) { - if (starts_with(i, "PRT")) { - mp.prt = i; + return mp; +} + + +/* Take some OSXDisk objects, representing disks that `DARegisterDiskAppearedCallback` told us about, + * and find those drives that we could write a DCP to. The drives returned are "real" (not synthesized) + * and are whole disks (not partitions). They may be mounted, or contain mounted partitions, in which + * their mounted() method will return true. + */ +vector +osx_disks_to_drives (vector disks) +{ + using namespace boost::algorithm; + + /* Mark disks containing mounted partitions as themselves mounted */ + for (auto& i: disks) { + if (!i.whole) { + continue; + } + for (auto& j: disks) { + if (!j.mount_points.empty() && starts_with(j.device, i.device)) { + LOG_DISK("Marking %1 as mounted because %2 is", i.device, j.device); + std::copy(j.mount_points.begin(), j.mount_points.end(), back_inserter(i.mount_points)); + } } } - return mp; -} + /* Mark containers of mounted synths as themselves mounted */ + for (auto& i: disks) { + if (i.media_path.real) { + for (auto& j: disks) { + if (!j.media_path.real && !j.mount_points.empty()) { + /* i is real, j is a mounted synth; if we see the first MEDIA_PATH_REQUIRED_MATCHES parts + * of i anywhere in j we assume they are related and so i shares j's mount points. + */ + bool one_missing = false; + string all_parts; + DCPOMATIC_ASSERT (i.media_path.parts.size() >= MEDIA_PATH_REQUIRED_MATCHES); + for (auto k = 0; k < MEDIA_PATH_REQUIRED_MATCHES; ++k) { + if (find(j.media_path.parts.begin(), j.media_path.parts.end(), i.media_path.parts[k]) == j.media_path.parts.end()) { + one_missing = true; + } + all_parts += i.media_path.parts[k] + " "; + } + + if (!one_missing) { + LOG_DISK("Marking %1 as mounted because %2 is (found %3)", i.device, j.device, all_parts); + std::copy(j.mount_points.begin(), j.mount_points.end(), back_inserter(i.mount_points)); + } + } + } + } + } + vector drives; + for (auto const& i: disks) { + if (i.whole && i.media_path.real) { + drives.push_back(Drive(i.device, i.mount_points, i.size, i.vendor, i.model)); + LOG_DISK_NC(drives.back().log_summary()); + } + } + return drives; +}