diff --git a/core/platform/FileUtils.cpp b/core/platform/FileUtils.cpp index 1f47ff635d..c7e24acc8d 100644 --- a/core/platform/FileUtils.cpp +++ b/core/platform/FileUtils.cpp @@ -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 diff --git a/core/platform/apple/FileUtils-apple.h b/core/platform/apple/FileUtils-apple.h index 04824c3a78..155a5f895c 100644 --- a/core/platform/apple/FileUtils-apple.h +++ b/core/platform/apple/FileUtils-apple.h @@ -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, diff --git a/core/platform/apple/FileUtils-apple.mm b/core/platform/apple/FileUtils-apple.mm index c99f4cf832..c91e2e9977 100644 --- a/core/platform/apple/FileUtils-apple.mm +++ b/core/platform/apple/FileUtils-apple.mm @@ -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