mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #8613 from hrydgard/iso-filesystem-lazy
"Lazy load" directory information in ISOFilesystem
This commit is contained in:
commit
f9ec9d53d0
2 changed files with 97 additions and 151 deletions
|
@ -28,7 +28,6 @@
|
||||||
#include "Core/MemMap.h"
|
#include "Core/MemMap.h"
|
||||||
#include "Core/Reporting.h"
|
#include "Core/Reporting.h"
|
||||||
|
|
||||||
|
|
||||||
const int sectorSize = 2048;
|
const int sectorSize = 2048;
|
||||||
|
|
||||||
bool parseLBN(std::string filename, u32 *sectorStart, u32 *readSize) {
|
bool parseLBN(std::string filename, u32 *sectorStart, u32 *readSize) {
|
||||||
|
@ -63,8 +62,7 @@ bool parseLBN(std::string filename, u32 *sectorStart, u32 *readSize) {
|
||||||
|
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
struct DirectoryEntry
|
struct DirectoryEntry {
|
||||||
{
|
|
||||||
u8 size;
|
u8 size;
|
||||||
u8 sectorsInExtendedRecord;
|
u8 sectorsInExtendedRecord;
|
||||||
u32_le firstDataSectorLE; // LBA
|
u32_le firstDataSectorLE; // LBA
|
||||||
|
@ -114,14 +112,13 @@ struct DirectoryEntry
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
struct DirectorySector
|
|
||||||
{
|
struct DirectorySector {
|
||||||
DirectoryEntry entry;
|
DirectoryEntry entry;
|
||||||
char space[2048-sizeof(DirectoryEntry)];
|
char space[2048-sizeof(DirectoryEntry)];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VolDescriptor
|
struct VolDescriptor {
|
||||||
{
|
|
||||||
char type;
|
char type;
|
||||||
char cd001[6];
|
char cd001[6];
|
||||||
char version;
|
char version;
|
||||||
|
@ -167,13 +164,10 @@ struct VolDescriptor
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevice, std::string _restrictPath)
|
ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevice, std::string _restrictPath) {
|
||||||
{
|
if (!_restrictPath.empty()) {
|
||||||
if (!_restrictPath.empty())
|
|
||||||
{
|
|
||||||
size_t pos = _restrictPath.find_first_not_of('/');
|
size_t pos = _restrictPath.find_first_not_of('/');
|
||||||
while (pos != _restrictPath.npos)
|
while (pos != _restrictPath.npos) {
|
||||||
{
|
|
||||||
size_t endPos = _restrictPath.find_first_of('/', pos);
|
size_t endPos = _restrictPath.find_first_of('/', pos);
|
||||||
if (endPos == _restrictPath.npos)
|
if (endPos == _restrictPath.npos)
|
||||||
endPos = _restrictPath.length();
|
endPos = _restrictPath.length();
|
||||||
|
@ -202,34 +196,34 @@ ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevic
|
||||||
treeroot->size = 0;
|
treeroot->size = 0;
|
||||||
treeroot->flags = 0;
|
treeroot->flags = 0;
|
||||||
treeroot->parent = NULL;
|
treeroot->parent = NULL;
|
||||||
|
treeroot->valid = false;
|
||||||
|
|
||||||
if (memcmp(desc.cd001, "CD001", 5)) {
|
if (memcmp(desc.cd001, "CD001", 5)) {
|
||||||
ERROR_LOG(FILESYS, "ISO looks bogus? Giving up...");
|
ERROR_LOG(FILESYS, "ISO looks bogus? Giving up...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 rootSector = desc.root.firstDataSector();
|
treeroot->startsector = desc.root.firstDataSector();
|
||||||
u32 rootSize = desc.root.dataLength();
|
treeroot->dirsize = desc.root.dataLength();
|
||||||
|
treeroot->level = 0;
|
||||||
ReadDirectory(rootSector, rootSize, treeroot, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ISOFileSystem::~ISOFileSystem()
|
ISOFileSystem::~ISOFileSystem() {
|
||||||
{
|
|
||||||
delete blockDevice;
|
delete blockDevice;
|
||||||
delete treeroot;
|
delete treeroot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, size_t level)
|
void ISOFileSystem::ReadDirectory(TreeEntry *root) {
|
||||||
{
|
for (u32 secnum = root->startsector, endsector = root->startsector + root->dirsize /2048; secnum < endsector; ++secnum) {
|
||||||
for (u32 secnum = startsector, endsector = dirsize/2048 + startsector; secnum < endsector; ++secnum)
|
|
||||||
{
|
|
||||||
u8 theSector[2048];
|
u8 theSector[2048];
|
||||||
blockDevice->ReadBlock(secnum, theSector);
|
if (!blockDevice->ReadBlock(secnum, theSector)) {
|
||||||
|
ERROR_LOG(FILESYS, "Error reading block for directory %s - skipping", root->name.c_str());
|
||||||
|
root->valid = true; // Prevents re-reading
|
||||||
|
return;
|
||||||
|
}
|
||||||
lastReadBlock_ = secnum;
|
lastReadBlock_ = secnum;
|
||||||
|
|
||||||
for (int offset = 0; offset < 2048; )
|
for (int offset = 0; offset < 2048; ) {
|
||||||
{
|
|
||||||
DirectoryEntry &dir = *(DirectoryEntry *)&theSector[offset];
|
DirectoryEntry &dir = *(DirectoryEntry *)&theSector[offset];
|
||||||
u8 sz = theSector[offset];
|
u8 sz = theSector[offset];
|
||||||
|
|
||||||
|
@ -238,8 +232,7 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const int IDENTIFIER_OFFSET = 33;
|
const int IDENTIFIER_OFFSET = 33;
|
||||||
if (offset + IDENTIFIER_OFFSET + dir.identifierLength > 2048)
|
if (offset + IDENTIFIER_OFFSET + dir.identifierLength > 2048) {
|
||||||
{
|
|
||||||
ERROR_LOG(FILESYS, "Directory entry crosses sectors, corrupt iso?");
|
ERROR_LOG(FILESYS, "Directory entry crosses sectors, corrupt iso?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -249,60 +242,51 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root,
|
||||||
bool isFile = (dir.flags & 2) ? false : true;
|
bool isFile = (dir.flags & 2) ? false : true;
|
||||||
bool relative;
|
bool relative;
|
||||||
|
|
||||||
TreeEntry *e = new TreeEntry();
|
TreeEntry *entry = new TreeEntry();
|
||||||
if (dir.identifierLength == 1 && (dir.firstIdChar == '\x00' || dir.firstIdChar == '.'))
|
if (dir.identifierLength == 1 && (dir.firstIdChar == '\x00' || dir.firstIdChar == '.')) {
|
||||||
{
|
entry->name = ".";
|
||||||
e->name = ".";
|
|
||||||
relative = true;
|
relative = true;
|
||||||
}
|
} else if (dir.identifierLength == 1 && dir.firstIdChar == '\x01') {
|
||||||
else if (dir.identifierLength == 1 && dir.firstIdChar == '\x01')
|
entry->name = "..";
|
||||||
{
|
|
||||||
e->name = "..";
|
|
||||||
relative = true;
|
relative = true;
|
||||||
}
|
} else {
|
||||||
else
|
entry->name = std::string((const char *)&dir.firstIdChar, dir.identifierLength);
|
||||||
{
|
|
||||||
e->name = std::string((const char *)&dir.firstIdChar, dir.identifierLength);
|
|
||||||
relative = false;
|
relative = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->size = dir.dataLength();
|
entry->size = dir.dataLength();
|
||||||
e->startingPosition = dir.firstDataSector() * 2048;
|
entry->startingPosition = dir.firstDataSector() * 2048;
|
||||||
e->isDirectory = !isFile;
|
entry->isDirectory = !isFile;
|
||||||
e->flags = dir.flags;
|
entry->flags = dir.flags;
|
||||||
e->parent = root;
|
entry->parent = root;
|
||||||
|
entry->startsector = dir.firstDataSector();
|
||||||
|
entry->dirsize = dir.dataLength();
|
||||||
|
entry->level = root->level + 1;
|
||||||
// Let's not excessively spam the log - I commented this line out.
|
// Let's not excessively spam the log - I commented this line out.
|
||||||
//DEBUG_LOG(FILESYS, "%s: %s %08x %08x %i", e->isDirectory?"D":"F", e->name.c_str(), dir.firstDataSectorLE, e->startingPosition, e->startingPosition);
|
//DEBUG_LOG(FILESYS, "%s: %s %08x %08x %i", e->isDirectory?"D":"F", e->name.c_str(), dir.firstDataSectorLE, e->startingPosition, e->startingPosition);
|
||||||
|
|
||||||
if (e->isDirectory && !relative)
|
if (entry->isDirectory && !relative) {
|
||||||
{
|
if (entry->startsector == root->startsector) {
|
||||||
if (dir.firstDataSector() == startsector)
|
ERROR_LOG(FILESYS, "WARNING: Appear to have a recursive file system, breaking recursion. Probably corrupt ISO.");
|
||||||
{
|
} else {
|
||||||
ERROR_LOG(FILESYS, "WARNING: Appear to have a recursive file system, breaking recursion");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool doRecurse = true;
|
bool doRecurse = true;
|
||||||
if (!restrictTree.empty())
|
if (!restrictTree.empty())
|
||||||
doRecurse = level < restrictTree.size() && restrictTree[level] == e->name;
|
doRecurse = root->level < restrictTree.size() && restrictTree[root->level] == entry->name;
|
||||||
|
|
||||||
if (doRecurse) {
|
if (!doRecurse) {
|
||||||
ReadDirectory(dir.firstDataSector(), dir.dataLength(), e, level + 1);
|
|
||||||
} else {
|
|
||||||
// The entry is not kept, must free it.
|
// The entry is not kept, must free it.
|
||||||
delete e;
|
delete entry;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root->children.push_back(e);
|
root->children.push_back(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
root->valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(const std::string &path, bool catchError)
|
ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(const std::string &path, bool catchError) {
|
||||||
{
|
|
||||||
const size_t pathLength = path.length();
|
const size_t pathLength = path.length();
|
||||||
|
|
||||||
if (pathLength == 0) {
|
if (pathLength == 0) {
|
||||||
|
@ -323,44 +307,39 @@ ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(const std::string &path, bo
|
||||||
if (pathLength <= pathIndex)
|
if (pathLength <= pathIndex)
|
||||||
return treeroot;
|
return treeroot;
|
||||||
|
|
||||||
TreeEntry *e = treeroot;
|
TreeEntry *entry = treeroot;
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
if (!entry->valid) {
|
||||||
TreeEntry *ne = nullptr;
|
ReadDirectory(entry);
|
||||||
|
}
|
||||||
|
TreeEntry *nextEntry = nullptr;
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
if (pathLength > pathIndex)
|
if (pathLength > pathIndex) {
|
||||||
{
|
|
||||||
size_t nextSlashIndex = path.find_first_of('/', pathIndex);
|
size_t nextSlashIndex = path.find_first_of('/', pathIndex);
|
||||||
if (nextSlashIndex == std::string::npos)
|
if (nextSlashIndex == std::string::npos)
|
||||||
nextSlashIndex = pathLength;
|
nextSlashIndex = pathLength;
|
||||||
|
|
||||||
const std::string firstPathComponent = path.substr(pathIndex, nextSlashIndex - pathIndex);
|
const std::string firstPathComponent = path.substr(pathIndex, nextSlashIndex - pathIndex);
|
||||||
for (size_t i = 0; i < e->children.size(); i++)
|
for (size_t i = 0; i < entry->children.size(); i++) {
|
||||||
{
|
const std::string &n = entry->children[i]->name;
|
||||||
const std::string &n = e->children[i]->name;
|
if (firstPathComponent == n) {
|
||||||
|
|
||||||
if (firstPathComponent == n)
|
|
||||||
{
|
|
||||||
//yay we got it
|
//yay we got it
|
||||||
ne = e->children[i];
|
nextEntry = entry->children[i];
|
||||||
name = n;
|
name = n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ne)
|
if (nextEntry) {
|
||||||
{
|
entry = nextEntry;
|
||||||
e = ne;
|
|
||||||
pathIndex += name.length();
|
pathIndex += name.length();
|
||||||
if (pathIndex < pathLength && path[pathIndex] == '/')
|
if (pathIndex < pathLength && path[pathIndex] == '/')
|
||||||
++pathIndex;
|
++pathIndex;
|
||||||
|
|
||||||
if (pathLength <= pathIndex)
|
if (pathLength <= pathIndex)
|
||||||
return e;
|
return entry;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (catchError)
|
if (catchError)
|
||||||
ERROR_LOG(FILESYS,"File %s not found", path.c_str());
|
ERROR_LOG(FILESYS,"File %s not found", path.c_str());
|
||||||
|
|
||||||
|
@ -369,28 +348,16 @@ ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(const std::string &path, bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename)
|
u32 ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) {
|
||||||
{
|
|
||||||
// LBN unittest
|
|
||||||
/*
|
|
||||||
u32 a, b;
|
|
||||||
if (parseLBN("/sce_lbn0x307aa_size0xefffe000", &a, &b)) {
|
|
||||||
ERROR_LOG(FILESYS, "lbn: %08x %08x", a, b);
|
|
||||||
} else {
|
|
||||||
ERROR_LOG(FILESYS, "faillbn: %08x %08x", a, b);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
OpenFileEntry entry;
|
OpenFileEntry entry;
|
||||||
entry.isRawSector = false;
|
entry.isRawSector = false;
|
||||||
entry.isBlockSectorMode = false;
|
entry.isBlockSectorMode = false;
|
||||||
|
|
||||||
if (filename.compare(0,8,"/sce_lbn") == 0)
|
if (filename.compare(0, 8, "/sce_lbn") == 0) {
|
||||||
{
|
// Raw sector read.
|
||||||
u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF;
|
u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF;
|
||||||
parseLBN(filename, §orStart, &readSize);
|
parseLBN(filename, §orStart, &readSize);
|
||||||
if (sectorStart > blockDevice->GetNumBlocks())
|
if (sectorStart > blockDevice->GetNumBlocks()) {
|
||||||
{
|
|
||||||
WARN_LOG(FILESYS, "Unable to open raw sector, out of range: %s, sector %08x, max %08x", filename.c_str(), sectorStart, blockDevice->GetNumBlocks());
|
WARN_LOG(FILESYS, "Unable to open raw sector, out of range: %s, sector %08x, max %08x", filename.c_str(), sectorStart, blockDevice->GetNumBlocks());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -408,15 +375,14 @@ u32 ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char
|
||||||
entry.openSize = readSize;
|
entry.openSize = readSize;
|
||||||
// when open as "umd1:/sce_lbn0x0_size0x6B49D200", that mean open umd1 as a block device.
|
// when open as "umd1:/sce_lbn0x0_size0x6B49D200", that mean open umd1 as a block device.
|
||||||
// the param in sceIoLseek and sceIoRead is lba mode. we must mark it.
|
// the param in sceIoLseek and sceIoRead is lba mode. we must mark it.
|
||||||
if(strncmp(devicename, "umd0:", 5)==0 || strncmp(devicename, "umd1:", 5)==0)
|
if (strncmp(devicename, "umd0:", 5)==0 || strncmp(devicename, "umd1:", 5)==0)
|
||||||
entry.isBlockSectorMode = true;
|
entry.isBlockSectorMode = true;
|
||||||
|
|
||||||
entries[newHandle] = entry;
|
entries[newHandle] = entry;
|
||||||
return newHandle;
|
return newHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access & FILEACCESS_WRITE)
|
if (access & FILEACCESS_WRITE) {
|
||||||
{
|
|
||||||
ERROR_LOG(FILESYS, "Can't open file %s with write access on an ISO partition", filename.c_str());
|
ERROR_LOG(FILESYS, "Can't open file %s with write access on an ISO partition", filename.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -437,24 +403,19 @@ u32 ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char
|
||||||
return newHandle;
|
return newHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISOFileSystem::CloseFile(u32 handle)
|
void ISOFileSystem::CloseFile(u32 handle) {
|
||||||
{
|
|
||||||
EntryMap::iterator iter = entries.find(handle);
|
EntryMap::iterator iter = entries.find(handle);
|
||||||
if (iter != entries.end())
|
if (iter != entries.end()) {
|
||||||
{
|
|
||||||
//CloseHandle((*iter).second.hFile);
|
//CloseHandle((*iter).second.hFile);
|
||||||
hAlloc->FreeHandle(handle);
|
hAlloc->FreeHandle(handle);
|
||||||
entries.erase(iter);
|
entries.erase(iter);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//This shouldn't happen...
|
//This shouldn't happen...
|
||||||
ERROR_LOG(FILESYS, "Hey, what are you doing? Closing non-open files?");
|
ERROR_LOG(FILESYS, "Hey, what are you doing? Closing non-open files?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ISOFileSystem::OwnsHandle(u32 handle)
|
bool ISOFileSystem::OwnsHandle(u32 handle) {
|
||||||
{
|
|
||||||
EntryMap::iterator iter = entries.find(handle);
|
EntryMap::iterator iter = entries.find(handle);
|
||||||
return (iter != entries.end());
|
return (iter != entries.end());
|
||||||
}
|
}
|
||||||
|
@ -620,23 +581,19 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ISOFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size)
|
size_t ISOFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size) {
|
||||||
{
|
|
||||||
ERROR_LOG(FILESYS, "Hey, what are you doing? You can't write to an ISO!");
|
ERROR_LOG(FILESYS, "Hey, what are you doing? You can't write to an ISO!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ISOFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec)
|
size_t ISOFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec) {
|
||||||
{
|
|
||||||
ERROR_LOG(FILESYS, "Hey, what are you doing? You can't write to an ISO!");
|
ERROR_LOG(FILESYS, "Hey, what are you doing? You can't write to an ISO!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ISOFileSystem::SeekFile(u32 handle, s32 position, FileMove type)
|
size_t ISOFileSystem::SeekFile(u32 handle, s32 position, FileMove type) {
|
||||||
{
|
|
||||||
EntryMap::iterator iter = entries.find(handle);
|
EntryMap::iterator iter = entries.find(handle);
|
||||||
if (iter != entries.end())
|
if (iter != entries.end()) {
|
||||||
{
|
|
||||||
OpenFileEntry &e = iter->second;
|
OpenFileEntry &e = iter->second;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -654,19 +611,15 @@ size_t ISOFileSystem::SeekFile(u32 handle, s32 position, FileMove type)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (size_t)e.seekPos;
|
return (size_t)e.seekPos;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//This shouldn't happen...
|
//This shouldn't happen...
|
||||||
ERROR_LOG(FILESYS, "Hey, what are you doing? Seeking in non-open files?");
|
ERROR_LOG(FILESYS, "Hey, what are you doing? Seeking in non-open files?");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename)
|
PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) {
|
||||||
{
|
if (filename.compare(0,8,"/sce_lbn") == 0) {
|
||||||
if (filename.compare(0,8,"/sce_lbn") == 0)
|
|
||||||
{
|
|
||||||
u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF;
|
u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF;
|
||||||
parseLBN(filename, §orStart, &readSize);
|
parseLBN(filename, §orStart, &readSize);
|
||||||
|
|
||||||
|
@ -682,13 +635,10 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename)
|
||||||
|
|
||||||
TreeEntry *entry = GetFromPath(filename, false);
|
TreeEntry *entry = GetFromPath(filename, false);
|
||||||
PSPFileInfo x;
|
PSPFileInfo x;
|
||||||
if (!entry)
|
if (!entry) {
|
||||||
{
|
|
||||||
x.size = 0;
|
x.size = 0;
|
||||||
x.exists = false;
|
x.exists = false;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
x.name = entry->name;
|
x.name = entry->name;
|
||||||
x.access = FILEACCESS_READ;
|
x.access = FILEACCESS_READ;
|
||||||
x.size = entry->size;
|
x.size = entry->size;
|
||||||
|
@ -700,8 +650,7 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename)
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PSPFileInfo> ISOFileSystem::GetDirListing(std::string path)
|
std::vector<PSPFileInfo> ISOFileSystem::GetDirListing(std::string path) {
|
||||||
{
|
|
||||||
std::vector<PSPFileInfo> myVector;
|
std::vector<PSPFileInfo> myVector;
|
||||||
TreeEntry *entry = GetFromPath(path);
|
TreeEntry *entry = GetFromPath(path);
|
||||||
if (! entry)
|
if (! entry)
|
||||||
|
@ -710,8 +659,7 @@ std::vector<PSPFileInfo> ISOFileSystem::GetDirListing(std::string path)
|
||||||
const std::string dot(".");
|
const std::string dot(".");
|
||||||
const std::string dotdot("..");
|
const std::string dotdot("..");
|
||||||
|
|
||||||
for (size_t i = 0; i < entry->children.size(); i++)
|
for (size_t i = 0; i < entry->children.size(); i++) {
|
||||||
{
|
|
||||||
TreeEntry *e = entry->children[i];
|
TreeEntry *e = entry->children[i];
|
||||||
|
|
||||||
// do not include the relative entries in the list
|
// do not include the relative entries in the list
|
||||||
|
@ -730,15 +678,13 @@ std::vector<PSPFileInfo> ISOFileSystem::GetDirListing(std::string path)
|
||||||
return myVector;
|
return myVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ISOFileSystem::EntryFullPath(TreeEntry *e)
|
std::string ISOFileSystem::EntryFullPath(TreeEntry *e) {
|
||||||
{
|
|
||||||
if (e == &entireISO)
|
if (e == &entireISO)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
size_t fullLen = 0;
|
size_t fullLen = 0;
|
||||||
TreeEntry *cur = e;
|
TreeEntry *cur = e;
|
||||||
while (cur != NULL && cur != treeroot)
|
while (cur != NULL && cur != treeroot) {
|
||||||
{
|
|
||||||
// For the "/".
|
// For the "/".
|
||||||
fullLen += 1 + cur->name.size();
|
fullLen += 1 + cur->name.size();
|
||||||
cur = cur->parent;
|
cur = cur->parent;
|
||||||
|
@ -765,8 +711,7 @@ ISOFileSystem::TreeEntry::~TreeEntry() {
|
||||||
children.clear();
|
children.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISOFileSystem::DoState(PointerWrap &p)
|
void ISOFileSystem::DoState(PointerWrap &p) {
|
||||||
{
|
|
||||||
auto s = p.Section("ISOFileSystem", 1, 2);
|
auto s = p.Section("ISOFileSystem", 1, 2);
|
||||||
if (!s)
|
if (!s)
|
||||||
return;
|
return;
|
||||||
|
@ -774,11 +719,9 @@ void ISOFileSystem::DoState(PointerWrap &p)
|
||||||
int n = (int) entries.size();
|
int n = (int) entries.size();
|
||||||
p.Do(n);
|
p.Do(n);
|
||||||
|
|
||||||
if (p.mode == p.MODE_READ)
|
if (p.mode == p.MODE_READ) {
|
||||||
{
|
|
||||||
entries.clear();
|
entries.clear();
|
||||||
for (int i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i) {
|
||||||
{
|
|
||||||
u32 fd = 0;
|
u32 fd = 0;
|
||||||
OpenFileEntry of;
|
OpenFileEntry of;
|
||||||
|
|
||||||
|
@ -801,11 +744,8 @@ void ISOFileSystem::DoState(PointerWrap &p)
|
||||||
|
|
||||||
entries[fd] = of;
|
entries[fd] = of;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
for (EntryMap::iterator it = entries.begin(), end = entries.end(); it != end; ++it) {
|
||||||
{
|
|
||||||
for (EntryMap::iterator it = entries.begin(), end = entries.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
OpenFileEntry &of = it->second;
|
OpenFileEntry &of = it->second;
|
||||||
p.Do(it->first);
|
p.Do(it->first);
|
||||||
p.Do(of.seekPos);
|
p.Do(of.seekPos);
|
||||||
|
|
|
@ -56,7 +56,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TreeEntry {
|
struct TreeEntry {
|
||||||
TreeEntry(){}
|
TreeEntry() : flags(0), valid(false) {}
|
||||||
~TreeEntry();
|
~TreeEntry();
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
@ -65,7 +65,13 @@ private:
|
||||||
s64 size;
|
s64 size;
|
||||||
bool isDirectory;
|
bool isDirectory;
|
||||||
|
|
||||||
|
u32 startsector;
|
||||||
|
u32 dirsize;
|
||||||
|
int level;
|
||||||
|
|
||||||
TreeEntry *parent;
|
TreeEntry *parent;
|
||||||
|
|
||||||
|
bool valid;
|
||||||
std::vector<TreeEntry *> children;
|
std::vector<TreeEntry *> children;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,7 +96,7 @@ private:
|
||||||
// Don't use this in the emu, not savestated.
|
// Don't use this in the emu, not savestated.
|
||||||
std::vector<std::string> restrictTree;
|
std::vector<std::string> restrictTree;
|
||||||
|
|
||||||
void ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, size_t level);
|
void ReadDirectory(TreeEntry *root);
|
||||||
TreeEntry *GetFromPath(const std::string &path, bool catchError = true);
|
TreeEntry *GetFromPath(const std::string &path, bool catchError = true);
|
||||||
std::string EntryFullPath(TreeEntry *e);
|
std::string EntryFullPath(TreeEntry *e);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue