JKRFileCache

This commit is contained in:
Jcw87
2023-09-22 18:59:11 -07:00
parent 1e91dff441
commit db18620f38
3 changed files with 339 additions and 64 deletions
+1 -1
View File
@@ -768,7 +768,7 @@ config.libs = [
Object(NonMatching, "JSystem/JKernel/JKRAramStream.cpp"),
Object(Matching, "JSystem/JKernel/JKRFileLoader.cpp"),
Object(Matching, "JSystem/JKernel/JKRFileFinder.cpp"),
Object(NonMatching, "JSystem/JKernel/JKRFileCache.cpp"),
Object(Matching, "JSystem/JKernel/JKRFileCache.cpp"),
Object(NonMatching, "JSystem/JKernel/JKRArchivePub.cpp"),
Object(NonMatching, "JSystem/JKernel/JKRArchivePri.cpp"),
Object(Matching, "JSystem/JKernel/JKRMemArchive.cpp"),
+4 -4
View File
@@ -41,10 +41,10 @@ public:
/* vt[12] */ virtual u32 getResSize(const void*) const; /* override */
/* vt[13] */ virtual u32 countFile(const char*) const; /* override */
/* vt[14] */ virtual JKRFileFinder* getFirstFile(const char*) const; /* override */
/* vt[15] */ virtual void* getFsResource(const char*);
/* vt[16] */ virtual void* getNameResource(u32, const char*);
/* vt[17] */ virtual u32 readFsResource(void*, u32, const char*);
/* vt[18] */ virtual u32 readNameResource(void*, u32, u32, const char*);
/* vt[15] */ virtual void* getFsResource(const char* path) { return getResource(path); }
/* vt[16] */ virtual void* getNameResource(u32 type, const char* path) { return getResource(type, path); }
/* vt[17] */ virtual u32 readFsResource(void* dst, u32 dstLength, const char* path) { return readResource(dst, dstLength, path); }
/* vt[18] */ virtual u32 readNameResource(void* dst, u32 dstLength, u32 type, const char* path) { return readResource(dst, dstLength, type, path); }
private:
/* 0x00 */ // vtable
+334 -59
View File
@@ -4,124 +4,399 @@
//
#include "JSystem/JKernel/JKRFileCache.h"
#include "dolphin/types.h"
#include "JSystem/JKernel/JKRDvdFile.h"
#include "JSystem/JKernel/JKRFileFinder.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "MSL_C/MSL_Common/Src/ctype.h"
#include "MSL_C/string.h"
#include "global.h"
/* 802B6FEC-802B70EC .text mount__12JKRFileCacheFPCcP7JKRHeapPCc */
void JKRFileCache::mount(const char*, JKRHeap*, const char*) {
/* Nonmatching */
JKRFileCache* JKRFileCache::mount(const char* path, JKRHeap* heap, const char* param_3) {
if (!path || *path != '/') {
return NULL;
}
u32 pathLength = strlen(path);
if (pathLength != 1 && path[pathLength - 1] == '/') {
return NULL;
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (iterator->getVolumeType() == 'CASH') {
JKRFileCache* fileCache = (JKRFileCache*)iterator.getObject();
if (fileCache->mRootPath) {
if (strcmp(fileCache->mRootPath, path) == 0) {
fileCache->mMountCount++;
return fileCache;
}
}
}
}
return new (heap, 0) JKRFileCache(path, param_3);
}
/* 802B70EC-802B72A8 .text __ct__12JKRFileCacheFPCcPCc */
JKRFileCache::JKRFileCache(const char*, const char*) {
/* Nonmatching */
JKRFileCache::JKRFileCache(const char* path, const char* volume) {
mParentHeap = JKRHeap::findFromRoot(this);
mMountCount = 1;
mVolumeType = 'CASH';
u32 pathLength = strlen(path);
mRootPath = (char*)JKRAllocFromHeap(mParentHeap, pathLength + 1, 1);
mCurrentPath = (char*)JKRAllocFromSysHeap(pathLength + 2, 1);
strcpy(mRootPath, path);
strcpy(mCurrentPath, path);
if (path[1] != '\0') {
convStrLower(mRootPath);
convStrLower(mCurrentPath);
strcat(mCurrentPath, "/");
const char* volumePath = volume;
if (!volume) {
volumePath = strrchr(mRootPath, '/');
volumePath++;
}
u32 volumeLength = strlen(volumePath) + 1;
mVolumePath = (char*)JKRAllocFromSysHeap(volumeLength, 0);
strcpy(mVolumePath, volumePath);
convStrLower(mVolumePath);
mVolumeName = mVolumePath;
} else {
const char* volumePath = volume;
if (!volume) {
volumePath = "dvd";
}
u32 volumeLength = strlen(volumePath) + 1;
mVolumePath = (char*)JKRAllocFromSysHeap(volumeLength, 0);
strcpy(mVolumePath, volumePath);
convStrLower(mVolumePath);
mVolumeName = mVolumePath;
}
getVolumeList().prepend(&mFileLoaderLink);
mIsMounted = true;
}
/* 802B72A8-802B737C .text __dt__12JKRFileCacheFv */
JKRFileCache::~JKRFileCache() {
/* Nonmatching */
removeResourceAll();
if (mRootPath)
JKRFreeToHeap(mParentHeap, mRootPath);
if (mCurrentPath)
JKRFreeToSysHeap(mCurrentPath);
if (mVolumePath)
JKRFreeToSysHeap(mVolumePath);
getVolumeList().remove(&mFileLoaderLink);
}
/* 802B737C-802B7410 .text becomeCurrent__12JKRFileCacheFPCc */
void JKRFileCache::becomeCurrent(const char*) {
/* Nonmatching */
bool JKRFileCache::becomeCurrent(const char* path) {
char* dvdPathName = getDvdPathName(path);
bool result = DVDChangeDir(dvdPathName);
if (result) {
sCurrentVolume = this;
JKRHeap::sSystemHeap->free(mCurrentPath);
mCurrentPath = dvdPathName;
if (mCurrentPath[1] != '\0') {
strcat(mCurrentPath, "/");
}
} else {
JKRHeap::sSystemHeap->free(dvdPathName);
}
return result;
}
/* 802B7410-802B7564 .text getResource__12JKRFileCacheFPCc */
void JKRFileCache::getResource(const char*) {
/* Nonmatching */
void* JKRFileCache::getResource(const char* path) {
JUT_ASSERT(237, isMounted());
void* buffer = NULL;
char* name = getDvdPathName(path);
JKRDvdFile dvdFile(name);
if (dvdFile.isAvailable()) {
CCacheBlock* cacheBlock = findCacheBlock(dvdFile.getFileID());
if (!cacheBlock) {
u32 fileSize = dvdFile.getFileInfo()->length;
u32 alignedSize = ALIGN_NEXT(fileSize, 0x20);
buffer = JKRAllocFromHeap(mParentHeap, alignedSize, 0x20);
if (buffer) {
dvdFile.read(buffer, alignedSize, 0);
cacheBlock = new (JKRHeap::getSystemHeap(), 0)
CCacheBlock(dvdFile.getFileID(), dvdFile.getFileInfo()->length, buffer);
mCacheBlockList.append(&cacheBlock->mCacheBlockLink);
}
} else {
cacheBlock->mReferenceCount++;
buffer = cacheBlock->mMemoryPtr;
}
}
JKRFreeToSysHeap(name);
return buffer;
}
/* 802B7564-802B7630 .text getResource__12JKRFileCacheFUlPCc */
void JKRFileCache::getResource(unsigned long, const char*) {
/* Nonmatching */
void* JKRFileCache::getResource(unsigned long, const char* path) {
JUT_ASSERT(303, isMounted());
char finalPath[256];
u32 rootLength = strlen(mRootPath);
char* filePath = finalPath + rootLength;
strcpy(finalPath, mRootPath);
bool found = findFile(finalPath, path);
if (found) {
return getResource(filePath);
}
return NULL;
}
/* 802B7630-802B7754 .text readResource__12JKRFileCacheFPvUlPCc */
void JKRFileCache::readResource(void*, unsigned long, const char*) {
/* Nonmatching */
u32 JKRFileCache::readResource(void* dst, u32 dstLength, const char* path) {
JUT_ASSERT(344, isMounted());
char* name = getDvdPathName(path);
JKRDvdFile dvdFile(name);
u32 resourceSize = 0;
while (true) {
if (!dvdFile.isAvailable()) {
break;
}
u32 fileSize = dvdFile.getFileInfo()->length;
resourceSize = ALIGN_NEXT(fileSize, 0x20);
dstLength = ALIGN_PREV(dstLength, 0x20);
if (resourceSize > dstLength) {
resourceSize = dstLength;
}
CCacheBlock* cacheBlock = findCacheBlock(dvdFile.getFileID());
if (!cacheBlock) {
dvdFile.read(dst, resourceSize, 0);
} else {
memcpy(dst, cacheBlock->mMemoryPtr, resourceSize);
}
}
JKRFreeToSysHeap(name);
return resourceSize;
}
/* 802B7754-802B7830 .text readResource__12JKRFileCacheFPvUlUlPCc */
void JKRFileCache::readResource(void*, unsigned long, unsigned long, const char*) {
/* Nonmatching */
u32 JKRFileCache::readResource(void* dst, u32 dstLength, u32, const char* path) {
JUT_ASSERT(412, isMounted());
char finalPath[256];
u32 rootLength = strlen(mRootPath);
char* filePath = finalPath + rootLength;
strcpy(finalPath, mRootPath);
bool found = findFile(finalPath, path);
if (found)
return readResource(dst, dstLength, filePath);
return NULL;
}
/* 802B7830-802B7904 .text removeResourceAll__12JKRFileCacheFv */
void JKRFileCache::removeResourceAll() {
/* Nonmatching */
JUT_ASSERT(441, isMounted());
JSUListIterator<CCacheBlock> iterator;
iterator = mCacheBlockList.getFirst();
while (iterator != mCacheBlockList.getEnd()) {
JKRFreeToHeap(mParentHeap, iterator->mMemoryPtr);
mCacheBlockList.remove(&iterator.getObject()->mCacheBlockLink);
CCacheBlock* cacheBlock = (iterator++).getObject();
delete cacheBlock;
}
}
/* 802B7904-802B79E4 .text removeResource__12JKRFileCacheFPv */
void JKRFileCache::removeResource(void*) {
/* Nonmatching */
bool JKRFileCache::removeResource(void* resource) {
JUT_ASSERT(463, isMounted());
CCacheBlock* cacheBlock = findCacheBlock(resource);
if (!cacheBlock)
return false;
u32 referenceCount = cacheBlock->mReferenceCount - 1;
cacheBlock->mReferenceCount = referenceCount;
if (referenceCount == 0) {
JKRFreeToHeap(mParentHeap, resource);
mCacheBlockList.remove(&cacheBlock->mCacheBlockLink);
delete cacheBlock;
}
return true;
}
/* 802B79E4-802B7AA8 .text detachResource__12JKRFileCacheFPv */
void JKRFileCache::detachResource(void*) {
/* Nonmatching */
bool JKRFileCache::detachResource(void* resource) {
JUT_ASSERT(490, isMounted());
CCacheBlock* cacheBlock = findCacheBlock(resource);
if (!cacheBlock)
return false;
mCacheBlockList.remove(&cacheBlock->mCacheBlockLink);
delete cacheBlock;
return true;
}
/* 802B7AA8-802B7ADC .text getResSize__12JKRFileCacheCFPCv */
void JKRFileCache::getResSize(const void*) const {
/* Nonmatching */
u32 JKRFileCache::getResSize(const void* resource) const {
CCacheBlock* cacheBlock = findCacheBlock(resource);
if (cacheBlock == NULL) {
return -1;
} else {
return cacheBlock->mFileSize;
}
}
/* 802B7ADC-802B7B58 .text countFile__12JKRFileCacheCFPCc */
void JKRFileCache::countFile(const char*) const {
/* Nonmatching */
u32 JKRFileCache::countFile(const char* path) const {
DVDDirectory dir;
DVDDirectoryEntry dirEntry;
u32 count = 0;
char* name = getDvdPathName(path);
BOOL result = DVDOpenDir(name, &dir);
if (result != 0) {
while (result = DVDReadDir(&dir, &dirEntry), result != FALSE) {
count = count + 1;
}
DVDCloseDir(&dir);
}
JKRFreeToSysHeap(name);
return count;
}
/* 802B7B58-802B7BF4 .text getFirstFile__12JKRFileCacheCFPCc */
void JKRFileCache::getFirstFile(const char*) const {
/* Nonmatching */
JKRFileFinder* JKRFileCache::getFirstFile(const char* path) const {
char* name = getDvdPathName(path);
JKRHeap* systemHeap = JKRHeap::getSystemHeap();
JKRDvdFinder* finder = new (systemHeap, 0) JKRDvdFinder(name);
JKRFreeToSysHeap(name);
if (finder->isAvailable() != true) {
delete finder;
return NULL;
}
return finder;
}
/* 802B7BF4-802B7C20 .text findCacheBlock__12JKRFileCacheCFPCv */
void JKRFileCache::findCacheBlock(const void*) const {
/* Nonmatching */
JKRFileCache::CCacheBlock* JKRFileCache::findCacheBlock(const void* resource) const {
JSUListIterator<CCacheBlock> iterator;
for (iterator = mCacheBlockList.getFirst(); iterator != mCacheBlockList.getEnd(); ++iterator) {
if (iterator->mMemoryPtr == resource) {
return iterator.getObject();
}
}
return NULL;
}
/* 802B7C20-802B7C4C .text findCacheBlock__12JKRFileCacheCFUl */
void JKRFileCache::findCacheBlock(unsigned long) const {
/* Nonmatching */
JKRFileCache::CCacheBlock* JKRFileCache::findCacheBlock(u32 fileID) const {
JSUListIterator<CCacheBlock> iterator;
for (iterator = mCacheBlockList.getFirst(); iterator != mCacheBlockList.getEnd(); ++iterator) {
if (iterator->mFileId == fileID) {
return iterator.getObject();
}
}
return NULL;
}
/* 802B7C4C-802B7D58 .text findFile__12JKRFileCacheCFPcPCc */
void JKRFileCache::findFile(char*, const char*) const {
/* Nonmatching */
bool JKRFileCache::findFile(char* path, const char* fileName) const {
DVDDirectory dir;
DVDDirectoryEntry dirEntry;
bool result = false;
u32 pathLength = strlen(path);
if (DVDOpenDir(path, &dir)) {
while (DVDReadDir(&dir, &dirEntry)) {
if (dirEntry.is_directory) {
char* endOfPath = path + pathLength;
*endOfPath = '/';
strcpy(path + pathLength + 1, dirEntry.name);
result = findFile(path, fileName);
if (result)
break;
*endOfPath = '\0';
} else {
result = (strcmp(fileName, dirEntry.name) == 0);
if (result) {
strcat(path, "/");
strcat(path, fileName);
break;
}
}
}
DVDCloseDir(&dir);
}
return result;
}
/* 802B7D58-802B7E60 .text getDvdPathName__12JKRFileCacheCFPCc */
void JKRFileCache::getDvdPathName(const char*) const {
/* Nonmatching */
char* JKRFileCache::getDvdPathName(const char* path) const {
char* newPath;
if (path[0] == '/') {
u32 length = strlen(mRootPath) + strlen(path) + 2;
newPath = (char*)JKRAllocFromSysHeap(length, 1);
strcpy(newPath, mRootPath);
if (path[1]) {
if (mRootPath[1] == 0) {
strcat(newPath, path + 1);
} else {
strcat(newPath, path);
}
}
} else {
u32 length = strlen(mCurrentPath) + strlen(path) + 2;
newPath = (char*)JKRAllocFromSysHeap(length, 1);
strcpy(newPath, mCurrentPath);
strcat(newPath, path);
}
convStrLower(newPath);
return newPath;
}
/* 802B7E60-802B7EA8 .text convStrLower__12JKRFileCacheCFPc */
void JKRFileCache::convStrLower(char*) const {
/* Nonmatching */
void JKRFileCache::convStrLower(char* buffer) const {
while (*buffer) {
*buffer++ = tolower(*buffer);
}
}
/* 802B7EA8-802B7F04 .text __ct__Q212JKRFileCache11CCacheBlockFUlUlPCv */
JKRFileCache::CCacheBlock::CCacheBlock(unsigned long, unsigned long, const void*) {
/* Nonmatching */
}
/* 802B7F04-802B7F30 .text getFsResource__12JKRFileCacheFPCc */
void JKRFileCache::getFsResource(const char*) {
/* Nonmatching */
}
/* 802B7F30-802B7F5C .text getNameResource__12JKRFileCacheFUlPCc */
void JKRFileCache::getNameResource(unsigned long, const char*) {
/* Nonmatching */
}
/* 802B7F5C-802B7F88 .text readFsResource__12JKRFileCacheFPvUlPCc */
void JKRFileCache::readFsResource(void*, unsigned long, const char*) {
/* Nonmatching */
}
/* 802B7F88-802B7FB4 .text readNameResource__12JKRFileCacheFPvUlUlPCc */
void JKRFileCache::readNameResource(void*, unsigned long, unsigned long, const char*) {
/* Nonmatching */
JKRFileCache::CCacheBlock::CCacheBlock(u32 fileId, u32 fileSize, const void* resource) : mCacheBlockLink(this) {
mReferenceCount = 1;
mFileId = fileId;
mFileSize = fileSize;
mMemoryPtr = (void*)resource; // todo: don't cast away const
}