From 3ab7e140ee8d33319b3279f6c445b686eac4c68f Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 16 Feb 2021 00:50:31 +1000 Subject: [PATCH] FileSystem: Add some overloads for FILE* --- src/common/file_system.cpp | 87 ++++++++++++++++++++++++++++++++++---- src/common/file_system.h | 3 ++ 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/src/common/file_system.cpp b/src/common/file_system.cpp index 7a176770e..6dd6717b8 100644 --- a/src/common/file_system.cpp +++ b/src/common/file_system.cpp @@ -483,14 +483,19 @@ std::optional> ReadBinaryFile(const char* filename) if (!fp) return std::nullopt; - std::fseek(fp.get(), 0, SEEK_END); - long size = std::ftell(fp.get()); - std::fseek(fp.get(), 0, SEEK_SET); + return ReadBinaryFile(fp.get()); +} + +std::optional> ReadBinaryFile(std::FILE* fp) +{ + std::fseek(fp, 0, SEEK_END); + long size = std::ftell(fp); + std::fseek(fp, 0, SEEK_SET); if (size < 0) return std::nullopt; std::vector res(static_cast(size)); - if (size > 0 && std::fread(res.data(), 1u, static_cast(size), fp.get()) != static_cast(size)) + if (size > 0 && std::fread(res.data(), 1u, static_cast(size), fp) != static_cast(size)) return std::nullopt; return res; @@ -502,15 +507,20 @@ std::optional ReadFileToString(const char* filename) if (!fp) return std::nullopt; - std::fseek(fp.get(), 0, SEEK_END); - long size = std::ftell(fp.get()); - std::fseek(fp.get(), 0, SEEK_SET); + return ReadFileToString(fp.get()); +} + +std::optional ReadFileToString(std::FILE* fp) +{ + std::fseek(fp, 0, SEEK_END); + long size = std::ftell(fp); + std::fseek(fp, 0, SEEK_SET); if (size < 0) return std::nullopt; std::string res; res.resize(static_cast(size)); - if (size > 0 && std::fread(res.data(), 1u, static_cast(size), fp.get()) != static_cast(size)) + if (size > 0 && std::fread(res.data(), 1u, static_cast(size), fp) != static_cast(size)) return std::nullopt; return res; @@ -1030,6 +1040,33 @@ bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* pStatData) return true; } +bool FileSystem::StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* pStatData) +{ + const int fd = _fileno(fp); + if (fd < 0) + return false; + + struct _stat64 st; + if (_fstati64(fd, &st) != 0) + return false; + + // parse attributes + pStatData->Attributes = 0; + if ((st.st_mode & _S_IFMT) == _S_IFDIR) + pStatData->Attributes |= FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY; + + // parse times + pStatData->ModificationTime.SetUnixTimestamp((Timestamp::UnixTimestampValue)st.st_mtime); + + // parse size + if ((st.st_mode & _S_IFMT) == _S_IFREG) + pStatData->Size = static_cast(st.st_size); + else + pStatData->Size = 0; + + return true; +} + bool FileSystem::FileExists(const char* path) { // has a path @@ -1485,6 +1522,40 @@ bool StatFile(const char* Path, FILESYSTEM_STAT_DATA* pStatData) return true; } +bool StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* pStatData) +{ + int fd = fileno(fp); + if (fd < 0) + return false; + + // stat file +#if defined(__HAIKU__) || defined(__APPLE__) + struct stat sysStatData; + if (fstat(fd, &sysStatData) < 0) +#else + struct stat64 sysStatData; + if (fstat64(fd, &sysStatData) < 0) +#endif + return false; + + // parse attributes + pStatData->Attributes = 0; + if (S_ISDIR(sysStatData.st_mode)) + pStatData->Attributes |= FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY; + + // parse times + pStatData->ModificationTime.SetUnixTimestamp((Timestamp::UnixTimestampValue)sysStatData.st_mtime); + + // parse size + if (S_ISREG(sysStatData.st_mode)) + pStatData->Size = static_cast(sysStatData.st_size); + else + pStatData->Size = 0; + + // ok + return true; +} + bool FileExists(const char* Path) { // has a path diff --git a/src/common/file_system.h b/src/common/file_system.h index 7b543e549..d2944797c 100644 --- a/src/common/file_system.h +++ b/src/common/file_system.h @@ -162,6 +162,7 @@ bool FindFiles(const char* Path, const char* Pattern, u32 Flags, FindResultsArra // stat file bool StatFile(const char* Path, FILESYSTEM_STAT_DATA* pStatData); +bool StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* pStatData); // file exists? bool FileExists(const char* Path); @@ -180,7 +181,9 @@ ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode); std::FILE* OpenCFile(const char* filename, const char* mode); std::optional> ReadBinaryFile(const char* filename); +std::optional> ReadBinaryFile(std::FILE* fp); std::optional ReadFileToString(const char* filename); +std::optional ReadFileToString(std::FILE* fp); bool WriteBinaryFile(const char* filename, const void* data, size_t data_length); bool WriteFileToString(const char* filename, const std::string_view& sv);