mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 11:00:19 +02:00
FEXCore/FileLoading: Updates helper to load file that is backed by memory
When attempting to read files that aren't backed by a filesystem then our current read file helpers fail since they query the file size upfront. Change the helper so that it doesn't query the size and just reads the file if it can be opened. This lets us read `/proc/self/maps` using helpers.
This commit is contained in:
1 parent
15c825f362
commit
b15f0b5d36
2 files changed
+53
-7
No files matched your search
@@ -24,24 +24,48 @@ static bool LoadFileImpl(T &Data, const fextl::string &Filepath, size_t FixedSiz
|
||||
size_t FileSize{};
|
||||
if (FixedSize == 0) {
|
||||
struct stat buf;
|
||||
if (fstat(FD, &buf) != 0) {
|
||||
close(FD);
|
||||
return false;
|
||||
if (fstat(FD, &buf) == 0) {
|
||||
FileSize = buf.st_size;
|
||||
}
|
||||
|
||||
FileSize = buf.st_size;
|
||||
}
|
||||
else {
|
||||
FileSize = FixedSize;
|
||||
}
|
||||
|
||||
ssize_t Read = -1;
|
||||
if (FileSize > 0) {
|
||||
bool LoadedFile{};
|
||||
if (FileSize) {
|
||||
// File size is known upfront
|
||||
Data.resize(FileSize);
|
||||
Read = pread(FD, &Data.at(0), FileSize, 0);
|
||||
|
||||
LoadedFile = Read == FileSize;
|
||||
}
|
||||
else {
|
||||
// The file is either empty or its size is unknown (e.g. procfs data).
|
||||
// Try reading in chunks instead
|
||||
ssize_t CurrentOffset = 0;
|
||||
constexpr size_t READ_SIZE = 4096;
|
||||
Data.resize(READ_SIZE);
|
||||
|
||||
while ((Read = pread(FD, &Data.at(CurrentOffset), READ_SIZE, CurrentOffset)) == READ_SIZE) {
|
||||
CurrentOffset += Read;
|
||||
Data.resize(CurrentOffset + Read);
|
||||
}
|
||||
|
||||
if (Read == -1) {
|
||||
Data.clear();
|
||||
close(FD);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Final resize to ensure there is no garbage data past the end.
|
||||
Data.resize(CurrentOffset + Read);
|
||||
|
||||
LoadedFile = true;
|
||||
}
|
||||
close(FD);
|
||||
return Read == FileSize;
|
||||
return LoadedFile;
|
||||
}
|
||||
|
||||
ssize_t LoadFileToBuffer(const fextl::string &Filepath, std::span<char> Buffer) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <FEXCore/Utils/FileLoading.h>
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
TEST_CASE("LoadFile-Doesn'tExist") {
|
||||
fextl::string MapsFile;
|
||||
auto Read = FEXCore::FileLoading::LoadFile(MapsFile, "/tmp/a/b/c/d/e/z");
|
||||
REQUIRE(MapsFile.size() == 0);
|
||||
REQUIRE(Read == false);
|
||||
}
|
||||
|
||||
TEST_CASE("LoadFile-procfs") {
|
||||
fextl::string MapsFile;
|
||||
FEXCore::FileLoading::LoadFile(MapsFile, "/proc/self/maps");
|
||||
REQUIRE(MapsFile.size() != 0);
|
||||
}
|
||||
|
||||
TEST_CASE("LoadFile-Buffer") {
|
||||
fextl::string MapsFile;
|
||||
MapsFile.resize(16);
|
||||
auto Read = FEXCore::FileLoading::LoadFileToBuffer("/proc/self/maps", MapsFile);
|
||||
REQUIRE(MapsFile.size() == Read);
|
||||
}
|
||||
Reference in new issue
Block a user