Fix FileUtils on macOS (#1863)

* Fix FileUtils::getFileSize() not returning -1 when file is not found

* Fix FileUtils::fullPathForDirectory() not appending a trailing slash

* Fix `not` and `and` keyword usage

* Fix FileUtils::getDefaultResourceRootPath() returning nothing on macOS

* Fix FileUtils::isFileExist() returning true for directories on macOS
This commit is contained in:
smilediver 2024-04-30 15:03:58 +03:00 committed by GitHub
parent edb4d47bc2
commit d845e54b49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 87 additions and 48 deletions

View File

@ -715,48 +715,58 @@ std::string FileUtils::fullPathForDirectory(std::string_view dir) const
{ {
DECLARE_GUARD; DECLARE_GUARD;
auto result = std::string();
if (dir.empty()) if (dir.empty())
{ {
return ""; // result is ""
} }
else if (isAbsolutePath(dir))
if (isAbsolutePath(dir))
{ {
return std::string{dir}; result = dir;
} }
else
// Already Cached ?
auto cacheIter = _fullPathCacheDir.find(dir);
if (cacheIter != _fullPathCacheDir.end())
{ {
return cacheIter->second; // Already Cached ?
} auto cacheIter = _fullPathCacheDir.find(dir);
std::string longdir{dir}; if (cacheIter != _fullPathCacheDir.end())
std::string fullpath;
if (longdir[longdir.length() - 1] != '/')
{
longdir += "/";
}
for (const auto& searchIt : _searchPathArray)
{
fullpath = this->getPathForDirectory(longdir, searchIt);
if (!fullpath.empty() && isDirectoryExistInternal(fullpath))
{ {
// Using the filename passed in as key. result = cacheIter->second;
_fullPathCacheDir.emplace(dir, fullpath); }
return fullpath; else
{
std::string longdir{dir};
if (longdir[longdir.length() - 1] != '/')
{
longdir += "/";
}
for (const auto& searchIt : _searchPathArray)
{
auto fullpath = this->getPathForDirectory(longdir, searchIt);
if (!fullpath.empty() && isDirectoryExistInternal(fullpath))
{
// Using the filename passed in as key.
_fullPathCacheDir.emplace(dir, fullpath);
result = fullpath;
break;
}
}
if (result.empty() && isPopupNotify())
{
AXLOG("axmol: fullPathForDirectory: No directory found at %s. Possible missing directory.", dir.data());
}
} }
} }
if (isPopupNotify()) if (!result.empty() && result.back() != '/')
{ {
AXLOG("axmol: fullPathForDirectory: No directory found at %s. Possible missing directory.", dir.data()); result += '/';
} }
// The file wasn't found, return empty string. return result;
return "";
} }
std::string FileUtils::fullPathFromRelativeFile(std::string_view filename, std::string_view relativeFile) const std::string FileUtils::fullPathFromRelativeFile(std::string_view filename, std::string_view relativeFile) const
@ -1330,7 +1340,7 @@ int64_t FileUtils::getFileSize(std::string_view filepath) const
{ {
fullpath = fullPathForFilename(filepath); fullpath = fullPathForFilename(filepath);
if (fullpath.empty()) if (fullpath.empty())
return 0; return -1;
path = fullpath; path = fullpath;
} }
else else

View File

@ -48,7 +48,9 @@ class AX_DLL FileUtilsApple : public FileUtils
public: public:
FileUtilsApple(); FileUtilsApple();
virtual ~FileUtilsApple(); virtual ~FileUtilsApple();
/* override functions */
virtual bool init() override;
virtual std::string getWritablePath() const override; virtual std::string getWritablePath() const override;
virtual std::string getNativeWritableAbsolutePath() const override; virtual std::string getNativeWritableAbsolutePath() const override;
virtual std::string getFullPathForFilenameWithinDirectory(std::string_view directory, virtual std::string getFullPathForFilenameWithinDirectory(std::string_view directory,

View File

@ -51,10 +51,26 @@ private:
NSBundle* bundle_; NSBundle* bundle_;
}; };
static std::string appendTrailingSlashToDir(std::string_view dir)
{
auto result = std::string(dir);
if (not result.empty() and result.back() != '/')
result.push_back('/');
return result;
}
FileUtilsApple::FileUtilsApple() : pimpl_(new IMPL([NSBundle mainBundle])) {} FileUtilsApple::FileUtilsApple() : pimpl_(new IMPL([NSBundle mainBundle])) {}
FileUtilsApple::~FileUtilsApple() = default; FileUtilsApple::~FileUtilsApple() = default;
bool FileUtilsApple::init()
{
_defaultResRootPath = appendTrailingSlashToDir([[[NSBundle mainBundle] resourcePath] UTF8String]);
bool ret = FileUtils::init();
return ret;
}
#if AX_FILEUTILS_APPLE_ENABLE_OBJC #if AX_FILEUTILS_APPLE_ENABLE_OBJC
void FileUtilsApple::setBundle(NSBundle* bundle) void FileUtilsApple::setBundle(NSBundle* bundle)
{ {
@ -132,13 +148,18 @@ bool FileUtilsApple::isFileExistInternal(std::string_view filePath) const
inDirectory:[NSString stringWithUTF8String:path.c_str()]]; inDirectory:[NSString stringWithUTF8String:path.c_str()]];
if (fullpath != nil) if (fullpath != nil)
{ {
ret = true; BOOL isDir = NO;
if ([s_fileManager fileExistsAtPath:fullpath isDirectory:&isDir] && !isDir)
{
ret = true;
}
} }
} }
else else
{ {
// Search path is an absolute path. // Search path is an absolute path.
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:filePath.data()]]) BOOL isDir = NO;
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:filePath.data()] isDirectory:&isDir] && !isDir)
{ {
ret = true; ret = true;
} }
@ -185,10 +206,10 @@ std::string FileUtilsApple::getPathForDirectory(std::string_view dir,
if (path[0] == '/') if (path[0] == '/')
{ {
BOOL isDir = false; BOOL isDir = NO;
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:path.data()] isDirectory:&isDir]) if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:path.data()] isDirectory:&isDir])
{ {
return isDir ? path : ""; return appendTrailingSlashToDir(isDir ? path : "");
} }
} }
else else
@ -197,7 +218,7 @@ std::string FileUtilsApple::getPathForDirectory(std::string_view dir,
ofType:nil]; ofType:nil];
if (fullpath != nil) if (fullpath != nil)
{ {
return [fullpath UTF8String]; return appendTrailingSlashToDir([fullpath UTF8String]);
} }
} }
return ""; return "";
@ -206,27 +227,33 @@ std::string FileUtilsApple::getPathForDirectory(std::string_view dir,
std::string FileUtilsApple::getFullPathForFilenameWithinDirectory(std::string_view directory, std::string FileUtilsApple::getFullPathForFilenameWithinDirectory(std::string_view directory,
std::string_view filename) const std::string_view filename) const
{ {
auto fullPath = std::string();
// Build full path for the file
if (directory[0] != '/') if (directory[0] != '/')
{ {
NSString* fullpath = [pimpl_->getBundle() pathForResource:[NSString stringWithUTF8String:filename.data()] NSString* path = [pimpl_->getBundle() pathForResource:[NSString stringWithUTF8String:filename.data()]
ofType:nil ofType:nil
inDirectory:[NSString stringWithUTF8String:directory.data()]]; inDirectory:[NSString stringWithUTF8String:directory.data()]];
if (fullpath != nil) if (path != nil)
{ {
return [fullpath UTF8String]; fullPath = [path UTF8String];
} }
} }
else else
{ {
std::string fullPath{directory}; fullPath = directory;
fullPath += filename; fullPath += filename;
// Search path is an absolute path.
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:fullPath.c_str()]])
{
return fullPath;
}
} }
return "";
// Check if there's a file at path
BOOL isDir = NO;
if (![s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:fullPath.c_str()] isDirectory:&isDir] || isDir)
{
fullPath.clear();
}
return fullPath;
} }
bool FileUtilsApple::createDirectory(std::string_view path) const bool FileUtilsApple::createDirectory(std::string_view path) const