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;
auto result = std::string();
if (dir.empty())
{
return "";
// result is ""
}
if (isAbsolutePath(dir))
else if (isAbsolutePath(dir))
{
return std::string{dir};
result = dir;
}
// Already Cached ?
auto cacheIter = _fullPathCacheDir.find(dir);
if (cacheIter != _fullPathCacheDir.end())
else
{
return cacheIter->second;
}
std::string longdir{dir};
std::string fullpath;
if (longdir[longdir.length() - 1] != '/')
{
longdir += "/";
}
for (const auto& searchIt : _searchPathArray)
{
fullpath = this->getPathForDirectory(longdir, searchIt);
if (!fullpath.empty() && isDirectoryExistInternal(fullpath))
// Already Cached ?
auto cacheIter = _fullPathCacheDir.find(dir);
if (cacheIter != _fullPathCacheDir.end())
{
// Using the filename passed in as key.
_fullPathCacheDir.emplace(dir, fullpath);
return fullpath;
result = cacheIter->second;
}
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 "";
return result;
}
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);
if (fullpath.empty())
return 0;
return -1;
path = fullpath;
}
else

View File

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

View File

@ -51,10 +51,26 @@ private:
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() = default;
bool FileUtilsApple::init()
{
_defaultResRootPath = appendTrailingSlashToDir([[[NSBundle mainBundle] resourcePath] UTF8String]);
bool ret = FileUtils::init();
return ret;
}
#if AX_FILEUTILS_APPLE_ENABLE_OBJC
void FileUtilsApple::setBundle(NSBundle* bundle)
{
@ -132,13 +148,18 @@ bool FileUtilsApple::isFileExistInternal(std::string_view filePath) const
inDirectory:[NSString stringWithUTF8String:path.c_str()]];
if (fullpath != nil)
{
ret = true;
BOOL isDir = NO;
if ([s_fileManager fileExistsAtPath:fullpath isDirectory:&isDir] && !isDir)
{
ret = true;
}
}
}
else
{
// 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;
}
@ -185,10 +206,10 @@ std::string FileUtilsApple::getPathForDirectory(std::string_view dir,
if (path[0] == '/')
{
BOOL isDir = false;
BOOL isDir = NO;
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:path.data()] isDirectory:&isDir])
{
return isDir ? path : "";
return appendTrailingSlashToDir(isDir ? path : "");
}
}
else
@ -197,7 +218,7 @@ std::string FileUtilsApple::getPathForDirectory(std::string_view dir,
ofType:nil];
if (fullpath != nil)
{
return [fullpath UTF8String];
return appendTrailingSlashToDir([fullpath UTF8String]);
}
}
return "";
@ -206,27 +227,33 @@ std::string FileUtilsApple::getPathForDirectory(std::string_view dir,
std::string FileUtilsApple::getFullPathForFilenameWithinDirectory(std::string_view directory,
std::string_view filename) const
{
auto fullPath = std::string();
// Build full path for the file
if (directory[0] != '/')
{
NSString* fullpath = [pimpl_->getBundle() pathForResource:[NSString stringWithUTF8String:filename.data()]
ofType:nil
inDirectory:[NSString stringWithUTF8String:directory.data()]];
if (fullpath != nil)
NSString* path = [pimpl_->getBundle() pathForResource:[NSString stringWithUTF8String:filename.data()]
ofType:nil
inDirectory:[NSString stringWithUTF8String:directory.data()]];
if (path != nil)
{
return [fullpath UTF8String];
fullPath = [path UTF8String];
}
}
else
{
std::string fullPath{directory};
fullPath = directory;
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