Skip to content

Commit

Permalink
FileSystem: Add Error parameter to more functions
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Jul 19, 2024
1 parent a6cf320 commit 41e1553
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 37 deletions.
143 changes: 109 additions & 34 deletions src/common/file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1107,20 +1107,35 @@ s64 FileSystem::FTell64(std::FILE* fp)
#endif
}

s64 FileSystem::FSize64(std::FILE* fp)
s64 FileSystem::FSize64(std::FILE* fp, Error* error)
{
const s64 pos = FTell64(fp);
if (pos >= 0)
if (pos < 0) [[unlikely]]
{
if (FSeek64(fp, 0, SEEK_END) == 0)
{
const s64 size = FTell64(fp);
if (FSeek64(fp, pos, SEEK_SET) == 0)
return size;
}
Error::SetErrno(error, "FTell64() failed: ", errno);
return -1;
}

return -1;
if (FSeek64(fp, 0, SEEK_END) != 0) [[unlikely]]
{
Error::SetErrno(error, "FSeek64() to end failed: ", errno);
return -1;
}

const s64 size = FTell64(fp);
if (size < 0) [[unlikely]]
{
Error::SetErrno(error, "FTell64() failed: ", errno);
return -1;
}

if (FSeek64(fp, pos, SEEK_SET) != 0)
{
Error::SetErrno(error, "FSeek64() to original position failed: ", errno);
return -1;
}

return size;
}

bool FileSystem::FTruncate64(std::FILE* fp, s64 size, Error* error)
Expand Down Expand Up @@ -1173,52 +1188,112 @@ s64 FileSystem::GetPathFileSize(const char* Path)

std::optional<std::vector<u8>> FileSystem::ReadBinaryFile(const char* filename, Error* error)
{
std::optional<std::vector<u8>> ret;

ManagedCFilePtr fp = OpenManagedCFile(filename, "rb", error);
if (!fp)
return std::nullopt;
return ret;

return ReadBinaryFile(fp.get());
ret = ReadBinaryFile(fp.get(), error);
return ret;
}

std::optional<std::vector<u8>> FileSystem::ReadBinaryFile(std::FILE* fp)
std::optional<std::vector<u8>> FileSystem::ReadBinaryFile(std::FILE* fp, Error* error)
{
std::fseek(fp, 0, SEEK_END);
const long size = std::ftell(fp);
std::fseek(fp, 0, SEEK_SET);
if (size < 0)
return std::nullopt;
std::optional<std::vector<u8>> ret;

std::vector<u8> res(static_cast<size_t>(size));
if (size > 0 && std::fread(res.data(), 1u, static_cast<size_t>(size), fp) != static_cast<size_t>(size))
return std::nullopt;
if (FSeek64(fp, 0, SEEK_END) != 0) [[unlikely]]
{
Error::SetErrno(error, "FSeek64() to end failed: ", errno);
return ret;
}

return res;
const s64 size = FTell64(fp);
if (size < 0) [[unlikely]]
{
Error::SetErrno(error, "FTell64() for length failed: ", errno);
return ret;
}

if constexpr (sizeof(s64) != sizeof(size_t))
{
if (size > static_cast<s64>(std::numeric_limits<long>::max())) [[unlikely]]
{
Error::SetStringFmt(error, "File size of {} is too large to read on this platform.", size);
return ret;
}
}

if (FSeek64(fp, 0, SEEK_SET) != 0) [[unlikely]]
{
Error::SetErrno(error, "FSeek64() to start failed: ", errno);
return ret;
}

ret = std::vector<u8>(static_cast<size_t>(size));
if (size > 0 && std::fread(ret->data(), 1u, static_cast<size_t>(size), fp) != static_cast<size_t>(size)) [[unlikely]]
{
Error::SetErrno(error, "fread() failed: ", errno);
ret.reset();
}

return ret;
}

std::optional<std::string> FileSystem::ReadFileToString(const char* filename, Error* error)
{
std::optional<std::string> ret;

ManagedCFilePtr fp = OpenManagedCFile(filename, "rb", error);
if (!fp)
return std::nullopt;
return ret;

return ReadFileToString(fp.get());
ret = ReadFileToString(fp.get());
return ret;
}

std::optional<std::string> FileSystem::ReadFileToString(std::FILE* fp)
std::optional<std::string> FileSystem::ReadFileToString(std::FILE* fp, Error* error)
{
std::fseek(fp, 0, SEEK_END);
const long size = std::ftell(fp);
std::fseek(fp, 0, SEEK_SET);
if (size < 0)
return std::nullopt;
std::optional<std::string> ret;

std::string res;
res.resize(static_cast<size_t>(size));
if (FSeek64(fp, 0, SEEK_END) != 0) [[unlikely]]
{
Error::SetErrno(error, "FSeek64() to end failed: ", errno);
return ret;
}

const s64 size = FTell64(fp);
if (size < 0) [[unlikely]]
{
Error::SetErrno(error, "FTell64() for length failed: ", errno);
return ret;
}

if constexpr (sizeof(s64) != sizeof(size_t))
{
if (size > static_cast<s64>(std::numeric_limits<long>::max())) [[unlikely]]
{
Error::SetStringFmt(error, "File size of {} is too large to read on this platform.", size);
return ret;
}
}

if (FSeek64(fp, 0, SEEK_SET) != 0) [[unlikely]]
{
Error::SetErrno(error, "FSeek64() to start failed: ", errno);
return ret;
}

ret = std::string();
ret->resize(static_cast<size_t>(size));
// NOTE - assumes mode 'rb', for example, this will fail over missing Windows carriage return bytes
if (size > 0 && std::fread(res.data(), 1u, static_cast<size_t>(size), fp) != static_cast<size_t>(size))
return std::nullopt;
if (size > 0 && std::fread(ret->data(), 1u, static_cast<size_t>(size), fp) != static_cast<size_t>(size))
{
Error::SetErrno(error, "fread() failed: ", errno);
ret.reset();
}

return res;
return ret;
}

bool FileSystem::WriteBinaryFile(const char* filename, const void* data, size_t data_length, Error* error)
Expand Down
6 changes: 3 additions & 3 deletions src/common/file_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode, Error*
std::FILE* OpenCFile(const char* filename, const char* mode, Error* error = nullptr);
int FSeek64(std::FILE* fp, s64 offset, int whence);
s64 FTell64(std::FILE* fp);
s64 FSize64(std::FILE* fp);
s64 FSize64(std::FILE* fp, Error* error = nullptr);
bool FTruncate64(std::FILE* fp, s64 size, Error* error = nullptr);

int OpenFDFile(const char* filename, int flags, int mode, Error* error = nullptr);
Expand Down Expand Up @@ -143,9 +143,9 @@ class POSIXLock
#endif

std::optional<std::vector<u8>> ReadBinaryFile(const char* filename, Error* error = nullptr);
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp, Error* error = nullptr);
std::optional<std::string> ReadFileToString(const char* filename, Error* error = nullptr);
std::optional<std::string> ReadFileToString(std::FILE* fp);
std::optional<std::string> ReadFileToString(std::FILE* fp, Error* error = nullptr);
bool WriteBinaryFile(const char* filename, const void* data, size_t data_length, Error* error = nullptr);
bool WriteStringToFile(const char* filename, std::string_view sv, Error* error = nullptr);

Expand Down

0 comments on commit 41e1553

Please sign in to comment.