From 5f9db20b4fb4f35d1810e54d58fc07e267691b42 Mon Sep 17 00:00:00 2001 From: Benau Date: Sat, 16 Apr 2022 12:08:57 +0800 Subject: [PATCH] Add IFileSystem::existFileOnly (not including directory) --- lib/irrlicht/include/IFileSystem.h | 4 +- lib/irrlicht/source/Irrlicht/CFileSystem.cpp | 41 +++++++++++++------- lib/irrlicht/source/Irrlicht/CFileSystem.h | 4 +- lib/irrlicht/source/Irrlicht/CReadFile.cpp | 18 +++++++-- src/io/file_manager.cpp | 2 +- src/io/file_manager.hpp | 2 +- 6 files changed, 46 insertions(+), 25 deletions(-) diff --git a/lib/irrlicht/include/IFileSystem.h b/lib/irrlicht/include/IFileSystem.h index f782a771b..3e05fe58b 100644 --- a/lib/irrlicht/include/IFileSystem.h +++ b/lib/irrlicht/include/IFileSystem.h @@ -326,10 +326,10 @@ public: \return True if file exists, and false if it does not exist or an error occured. */ virtual bool existFile(const path& filename) const =0; - //! Determines if a file exists and could be opened (thread-safe, ignore file archives). + //! Determines if a file exists and could be opened (thread-safe, ignore file archives), this function returns false for directory /** \param filename is the string identifying the file which should be tested for existence. \return True if file exists, and false if it does not exist or an error occured. */ - virtual bool existFileThreadSafe(const path& filename) const =0; + virtual bool existFileOnly(const path& filename) const =0; //! Creates a XML Reader from a file which returns all parsed strings as wide characters (wchar_t*). /** Use createXMLReaderUTF8() if you prefer char* instead of wchar_t*. See IIrrXMLReader for diff --git a/lib/irrlicht/source/Irrlicht/CFileSystem.cpp b/lib/irrlicht/source/Irrlicht/CFileSystem.cpp index cdb6d01ea..f2bc8ef8c 100644 --- a/lib/irrlicht/source/Irrlicht/CFileSystem.cpp +++ b/lib/irrlicht/source/Irrlicht/CFileSystem.cpp @@ -20,6 +20,8 @@ #include "CLimitReadFile.h" #include "irrList.h" +#include "io/file_manager.hpp" + #if defined (_IRR_WINDOWS_API_) #include "utils/string_utils.hpp" #if !defined ( _WIN32_WCE ) @@ -958,10 +960,31 @@ IFileList* CFileSystem::createEmptyFileList(const io::path& path, bool ignoreCas return new CFileList(path, ignoreCase, ignorePaths); } - -//! Determines if a file exists and could be opened (thread-safe, ignore file archives). -bool CFileSystem::existFileThreadSafe(const path& filename) const +//! Determines if a file exists and could be opened (thread-safe, ignore file archives), this function returns false for directory +bool CFileSystem::existFileOnly(const path& filename) const { + if (FileManager::isDirectory(filename.c_str())) + return false; + + io::IReadFile* file = createReadFile(filename); + if (file) + { + file->drop(); + return true; + } + return false; +} + + +//! determines if a file exists and would be able to be opened. +bool CFileSystem::existFile(const io::path& filename) const +{ + std::unique_lock ul(m_file_archives_mutex); + for (u32 i=0; i < FileArchives.size(); ++i) + if (FileArchives[i]->getFileList()->findFile(filename)!=-1) + return true; + ul.unlock(); + #if defined(_IRR_WINDOWS_CE_PLATFORM_) #if defined(_IRR_WCHAR_FILESYSTEM) HANDLE hFile = CreateFileW(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); @@ -998,18 +1021,6 @@ bool CFileSystem::existFileThreadSafe(const path& filename) const } -//! determines if a file exists and would be able to be opened. -bool CFileSystem::existFile(const io::path& filename) const -{ - std::unique_lock ul(m_file_archives_mutex); - for (u32 i=0; i < FileArchives.size(); ++i) - if (FileArchives[i]->getFileList()->findFile(filename)!=-1) - return true; - ul.unlock(); - return existFileThreadSafe(filename); -} - - //! Creates a XML Reader from a file. IXMLReader* CFileSystem::createXMLReader(const io::path& filename) { diff --git a/lib/irrlicht/source/Irrlicht/CFileSystem.h b/lib/irrlicht/source/Irrlicht/CFileSystem.h index ed605cd7a..48b5297c4 100644 --- a/lib/irrlicht/source/Irrlicht/CFileSystem.h +++ b/lib/irrlicht/source/Irrlicht/CFileSystem.h @@ -133,8 +133,8 @@ public: //! determines if a file exists and would be able to be opened. virtual bool existFile(const io::path& filename) const; - //! Determines if a file exists and could be opened (thread-safe, ignore file archives). - virtual bool existFileThreadSafe(const path& filename) const; + //! Determines if a file exists and could be opened (thread-safe, ignore file archives), this function returns false for directory + virtual bool existFileOnly(const path& filename) const; //! Creates a XML Reader from a file. virtual IXMLReader* createXMLReader(const io::path& filename); diff --git a/lib/irrlicht/source/Irrlicht/CReadFile.cpp b/lib/irrlicht/source/Irrlicht/CReadFile.cpp index 801754986..43c13a54b 100644 --- a/lib/irrlicht/source/Irrlicht/CReadFile.cpp +++ b/lib/irrlicht/source/Irrlicht/CReadFile.cpp @@ -78,12 +78,22 @@ void CReadFile::openFile() if (File) { - // get FileSize + // get FileSize, check for errors + // See https://stackoverflow.com/questions/18192998/plain-c-opening-a-directory-with-fopen - fseek(File, 0, SEEK_END); - FileSize = getPos(); - fseek(File, 0, SEEK_SET); + if (fseek(File, 0, SEEK_END) < 0) + goto error; + s32 file_size = (s32)ftell(File); + if (file_size == -1) + goto error; + FileSize = file_size; + if (fseek(File, 0, SEEK_SET) < 0) + goto error; } + return; +error: + fclose(File); + File = 0; } diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index d25c8b76f..b943cb665 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -1439,7 +1439,7 @@ std::string FileManager::searchModel(const std::string& file_name) const /** Returns true if the given name is a directory. * \param path File name to test. */ -bool FileManager::isDirectory(const std::string &path) const +bool FileManager::isDirectory(const std::string &path) { struct stat mystat; std::string s(path); diff --git a/src/io/file_manager.hpp b/src/io/file_manager.hpp index 04a4afed1..d6eb1586a 100644 --- a/src/io/file_manager.hpp +++ b/src/io/file_manager.hpp @@ -157,7 +157,7 @@ public: const std::string &getAddonsDir() const; std::string getAddonsFile(const std::string &name); void checkAndCreateDirForAddons(const std::string &dir); - bool isDirectory(const std::string &path) const; + static bool isDirectory(const std::string &path); bool removeFile(const std::string &name) const; bool removeDirectory(const std::string &name) const; // ------------------------------------------------------------------------