Io: Provide directory existence with listing.

Sometimes, you need to tell the difference between an empty directory and
one that doesn't exist at all.  We can do this in a single call.
This commit is contained in:
Unknown W. Brackets 2022-10-09 09:08:18 -07:00
parent 7b8350f8a8
commit 4942692558
11 changed files with 66 additions and 29 deletions

View file

@ -30,9 +30,11 @@ void BlobFileSystem::DoState(PointerWrap &p) {
// Not used in real emulation.
}
std::vector<PSPFileInfo> BlobFileSystem::GetDirListing(std::string path) {
std::vector<PSPFileInfo> BlobFileSystem::GetDirListing(const std::string &path, bool *exists) {
std::vector<PSPFileInfo> listing;
listing.push_back(GetFileInfo(alias_));
if (exists)
*exists = true;
return listing;
}

View file

@ -34,7 +34,7 @@ public:
~BlobFileSystem();
void DoState(PointerWrap &p) override;
std::vector<PSPFileInfo> GetDirListing(std::string path) override;
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override;
int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override;
void CloseFile(u32 handle) override;
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override;

View file

@ -789,7 +789,7 @@ bool DirectoryFileSystem::ComputeRecursiveDirSizeIfFast(const std::string &path,
}
}
std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(std::string path) {
std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(const std::string &path, bool *exists) {
std::vector<PSPFileInfo> myVector;
std::vector<File::FileInfo> files;
@ -798,14 +798,19 @@ std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(std::string path) {
if (!File::GetFilesInDir(localPath, &files, nullptr, flags)) {
// TODO: Case sensitivity should be checked on a file system basis, right?
#if HOST_IS_CASE_SENSITIVE
if (FixPathCase(basePath, path, FPC_FILE_MUST_EXIST)) {
std::string fixedPath = path;
if (FixPathCase(basePath, fixedPath, FPC_FILE_MUST_EXIST)) {
// May have failed due to case sensitivity, try again
localPath = GetLocalPath(path);
localPath = GetLocalPath(fixedPath);
if (!File::GetFilesInDir(localPath, &files, nullptr, 0)) {
if (exists)
*exists = false;
return ReplayApplyDiskListing(myVector, CoreTiming::GetGlobalTimeUs());
}
}
#else
if (exists)
*exists = false;
return ReplayApplyDiskListing(myVector, CoreTiming::GetGlobalTimeUs());
#endif
}
@ -835,6 +840,7 @@ std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(std::string path) {
entry.type = FILETYPE_NORMAL;
}
entry.access = file.access;
entry.exists = file.exists;
localtime_r((time_t*)&file.atime, &entry.atime);
localtime_r((time_t*)&file.ctime, &entry.ctime);
@ -843,6 +849,8 @@ std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(std::string path) {
myVector.push_back(entry);
}
if (exists)
*exists = true;
return ReplayApplyDiskListing(myVector, CoreTiming::GetGlobalTimeUs());
}
@ -1073,9 +1081,11 @@ size_t VFSFileSystem::SeekFile(u32 handle, s32 position, FileMove type) {
}
}
std::vector<PSPFileInfo> VFSFileSystem::GetDirListing(std::string path) {
std::vector<PSPFileInfo> VFSFileSystem::GetDirListing(const std::string &path, bool *exists) {
std::vector<PSPFileInfo> myVector;
// TODO
if (exists)
*exists = false;
return myVector;
}

View file

@ -65,7 +65,7 @@ public:
void CloseAll();
void DoState(PointerWrap &p) override;
std::vector<PSPFileInfo> GetDirListing(std::string path) override;
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override;
int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override;
void CloseFile(u32 handle) override;
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override;
@ -111,7 +111,7 @@ public:
~VFSFileSystem();
void DoState(PointerWrap &p) override;
std::vector<PSPFileInfo> GetDirListing(std::string path) override;
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override;
int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override;
void CloseFile(u32 handle) override;
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override;

View file

@ -118,7 +118,7 @@ public:
virtual ~IFileSystem() {}
virtual void DoState(PointerWrap &p) = 0;
virtual std::vector<PSPFileInfo> GetDirListing(std::string path) = 0;
virtual std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) = 0;
virtual int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) = 0;
virtual void CloseFile(u32 handle) = 0;
virtual size_t ReadFile(u32 handle, u8 *pointer, s64 size) = 0;
@ -143,7 +143,12 @@ public:
class EmptyFileSystem : public IFileSystem {
public:
virtual void DoState(PointerWrap &p) override {}
std::vector<PSPFileInfo> GetDirListing(std::string path) override {std::vector<PSPFileInfo> vec; return vec;}
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override {
if (exists)
*exists = false;
std::vector<PSPFileInfo> vec;
return vec;
}
int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override {return SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND;}
void CloseFile(u32 handle) override {}
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override {return 0;}

View file

@ -631,11 +631,14 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) {
return x;
}
std::vector<PSPFileInfo> ISOFileSystem::GetDirListing(std::string path) {
std::vector<PSPFileInfo> ISOFileSystem::GetDirListing(const std::string &path, bool *exists) {
std::vector<PSPFileInfo> myVector;
TreeEntry *entry = GetFromPath(path);
if (!entry)
if (!entry) {
if (exists)
*exists = false;
return myVector;
}
const std::string dot(".");
const std::string dotdot("..");
@ -651,6 +654,7 @@ std::vector<PSPFileInfo> ISOFileSystem::GetDirListing(std::string path) {
x.name = e->name;
// Strangely, it seems to be executable even for files.
x.access = 0555;
x.exists = true;
x.size = e->size;
x.type = e->isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL;
x.isOnSectorSystem = true;
@ -659,6 +663,8 @@ std::vector<PSPFileInfo> ISOFileSystem::GetDirListing(std::string path) {
x.numSectors = (u32)((e->size + sectorSize - 1) / sectorSize);
myVector.push_back(x);
}
if (exists)
*exists = true;
return myVector;
}

View file

@ -33,7 +33,7 @@ public:
~ISOFileSystem();
void DoState(PointerWrap &p) override;
std::vector<PSPFileInfo> GetDirListing(std::string path) override;
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override;
int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override;
void CloseFile(u32 handle) override;
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override;
@ -110,7 +110,11 @@ public:
isoFileSystem_->DoState(p);
}
std::vector<PSPFileInfo> GetDirListing(std::string path) override { return std::vector<PSPFileInfo>(); }
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override {
if (exists)
*exists = true;
return std::vector<PSPFileInfo>();
}
int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override {
return isoFileSystem_->OpenFile("", access, devicename);
}

View file

@ -369,19 +369,17 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename)
}
}
std::vector<PSPFileInfo> MetaFileSystem::GetDirListing(std::string path)
{
std::vector<PSPFileInfo> MetaFileSystem::GetDirListing(const std::string &path, bool *exists) {
std::lock_guard<std::recursive_mutex> guard(lock);
std::string of;
IFileSystem *system;
int error = MapFilePath(path, of, &system);
if (error == 0)
{
return system->GetDirListing(of);
}
else
{
if (error == 0) {
return system->GetDirListing(of, exists);
} else {
std::vector<PSPFileInfo> empty;
if (exists)
*exists = false;
return empty;
}
}

View file

@ -103,7 +103,7 @@ public:
std::string NormalizePrefix(std::string prefix) const;
std::vector<PSPFileInfo> GetDirListing(std::string path) override;
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override;
int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override;
void CloseFile(u32 handle) override;
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override;

View file

@ -661,8 +661,7 @@ static void tmFromFiletime(tm &dest, FILETIME &src)
}
#endif
std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(std::string path)
{
std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(const std::string &path, bool *exists) {
std::vector<PSPFileInfo> myVector;
// TODO(scoped): Switch this over to GetFilesInDir!
@ -681,9 +680,14 @@ std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(std::string path)
hFind = FindFirstFileEx(w32path.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0);
#endif
if (hFind == INVALID_HANDLE_VALUE) {
if (exists)
*exists = false;
return myVector; //the empty list
}
if (exists)
*exists = true;
for (BOOL retval = 1; retval; retval = FindNextFile(hFind, &findData)) {
if (!wcscmp(findData.cFileName, L"..") || !wcscmp(findData.cFileName, L".")) {
continue;
@ -697,6 +701,7 @@ std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(std::string path)
}
entry.access = 0555;
entry.exists = true;
entry.size = findData.nFileSizeLow | ((u64)findData.nFileSizeHigh<<32);
entry.name = ConvertWStringToUTF8(findData.cFileName);
tmFromFiletime(entry.atime, findData.ftLastAccessTime);
@ -717,18 +722,24 @@ std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(std::string path)
DIR *dp = opendir(localPath.c_str());
#if HOST_IS_CASE_SENSITIVE
if(dp == NULL && FixPathCase(basePath, path, FPC_FILE_MUST_EXIST)) {
std::string fixedPath = path;
if(dp == NULL && FixPathCase(basePath, fixedPath, FPC_FILE_MUST_EXIST)) {
// May have failed due to case sensitivity, try again
localPath = GetLocalPath(path);
localPath = GetLocalPath(fixedPath);
dp = opendir(localPath.c_str());
}
#endif
if (dp == NULL) {
ERROR_LOG(FILESYS,"Error opening directory %s\n", path.c_str());
if (exists)
*exists = false;
return myVector;
}
if (exists)
*exists = true;
while ((dirp = readdir(dp)) != NULL) {
if (!strcmp(dirp->d_name, "..") || !strcmp(dirp->d_name, ".")) {
continue;
@ -736,13 +747,14 @@ std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(std::string path)
PSPFileInfo entry;
struct stat s;
std::string fullName = (GetLocalPath(path) / std::string(dirp->d_name)).ToString();
std::string fullName = (localPath / std::string(dirp->d_name)).ToString();
stat(fullName.c_str(), &s);
if (S_ISDIR(s.st_mode))
entry.type = FILETYPE_DIRECTORY;
else
entry.type = FILETYPE_NORMAL;
entry.access = 0555;
entry.exists = true;
entry.name = dirp->d_name;
entry.size = s.st_size;
localtime_r((time_t*)&s.st_atime,&entry.atime);

View file

@ -40,7 +40,7 @@ public:
bool OwnsHandle(u32 handle) override;
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override;
PSPDevType DevType(u32 handle) override;
std::vector<PSPFileInfo> GetDirListing(std::string path) override;
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override;
FileSystemFlags Flags() override { return FileSystemFlags::UMD; }
u64 FreeSpace(const std::string &path) override { return 0; }