diff options
| author | Carl Hetherington <cth@carlh.net> | 2023-10-06 02:04:49 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2023-10-09 01:20:01 +0200 |
| commit | e4b2ebd80779a44d24fe87af26ef278c1e2d97d2 (patch) | |
| tree | 3bc940c5eb49c96c3c18a896c8ccd8039e6db839 /src/file.cc | |
| parent | 3be26a66645de04c7b220abeebfd2f024990a696 (diff) | |
Add wrappers around boost::filesystem methods that handle the
required mangling of long filenames on Windows.
Also wrap lots of missing places (e.g. calls to asdcplib, libxml++,
libcxml etc.) in dcp::filesystem::fix_long_path().
The idea is to keep paths un-mangled until they we call some
filesystem-related API and mangle them at that point. Otherwise
we end up serialising mangled names, which seems like it will
not end well.
Should fix DoM #2623.
Diffstat (limited to 'src/file.cc')
| -rw-r--r-- | src/file.cc | 46 |
1 files changed, 2 insertions, 44 deletions
diff --git a/src/file.cc b/src/file.cc index b5d2eed4..36102f72 100644 --- a/src/file.cc +++ b/src/file.cc @@ -34,7 +34,7 @@ #include "dcp_assert.h" #include "file.h" -#include <boost/algorithm/string.hpp> +#include "filesystem.h" #ifdef LIBDCP_WINDOWS #include <errhandlingapi.h> #endif @@ -57,7 +57,7 @@ File::File(boost::filesystem::path path, std::string mode) SetLastError(0); std::wstring mode_wide(mode.begin(), mode.end()); /* c_str() here should give a UTF-16 string */ - _file = _wfopen(fix_long_path(path).c_str(), mode_wide.c_str()); + _file = _wfopen(dcp::filesystem::fix_long_path(path).c_str(), mode_wide.c_str()); if (!_file) { _open_error = GetLastError(); } @@ -216,45 +216,3 @@ File::error () DCP_ASSERT(_file); return ferror(_file); } - - -/** Windows can't "by default" cope with paths longer than 260 characters, so if you pass such a path to - * any boost::filesystem method it will fail. There is a "fix" for this, which is to prepend - * the string \\?\ to the path. This will make it work, so long as: - * - the path is absolute. - * - the path only uses backslashes. - * - individual path components are "short enough" (probably less than 255 characters) - * - * See https://www.boost.org/doc/libs/1_57_0/libs/filesystem/doc/reference.html under - * "Warning: Long paths on Windows" for some details. - * - * Our fopen_boost uses this method to get this fix, but any other calls to boost::filesystem - * will not unless this method is explicitly called to pre-process the pathname. - */ -boost::filesystem::path -dcp::fix_long_path (boost::filesystem::path long_path) -{ -#ifdef LIBDCP_WINDOWS - using namespace boost::filesystem; - - if (boost::algorithm::starts_with(long_path.string(), "\\\\")) { - /* This could mean it starts with \\ (i.e. a SMB path) or \\?\ (a long path) - * or a variety of other things... anyway, we'll leave it alone. - */ - return long_path; - } - - /* We have to make the path canonical but we can't call canonical() on the long path - * as it will fail. So we'll sort of do it ourselves (possibly badly). - */ - path fixed = "\\\\?\\"; - if (long_path.is_absolute()) { - fixed += long_path.make_preferred(); - } else { - fixed += boost::filesystem::current_path() / long_path.make_preferred(); - } - return fixed; -#else - return long_path; -#endif -} |
