summaryrefslogtreecommitdiff
path: root/src/JSystem/JKernel/JKRFileCache.cpp
diff options
context:
space:
mode:
authorJcw87 <Jcw87@users.noreply.github.com>2023-09-22 18:59:11 -0700
committerJcw87 <Jcw87@users.noreply.github.com>2023-09-24 01:45:16 -0700
commitdb18620f38e69b0832d4bf905081ea1002014ece (patch)
tree5a80677c48482fd84cecd276fd4c872a6ef5857b /src/JSystem/JKernel/JKRFileCache.cpp
parent1e91dff441bffa1187991ffbff18f096b4727d8a (diff)
JKRFileCache
Diffstat (limited to 'src/JSystem/JKernel/JKRFileCache.cpp')
-rw-r--r--src/JSystem/JKernel/JKRFileCache.cpp391
1 files changed, 333 insertions, 58 deletions
diff --git a/src/JSystem/JKernel/JKRFileCache.cpp b/src/JSystem/JKernel/JKRFileCache.cpp
index 26190b9d..89f60a24 100644
--- a/src/JSystem/JKernel/JKRFileCache.cpp
+++ b/src/JSystem/JKernel/JKRFileCache.cpp
@@ -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;
-/* 802B7D58-802B7E60 .text getDvdPathName__12JKRFileCacheCFPCc */
-void JKRFileCache::getDvdPathName(const char*) const {
- /* Nonmatching */
-}
+ 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;
+ }
+ }
+ }
-/* 802B7E60-802B7EA8 .text convStrLower__12JKRFileCacheCFPc */
-void JKRFileCache::convStrLower(char*) const {
- /* Nonmatching */
-}
+ DVDCloseDir(&dir);
+ }
-/* 802B7EA8-802B7F04 .text __ct__Q212JKRFileCache11CCacheBlockFUlUlPCv */
-JKRFileCache::CCacheBlock::CCacheBlock(unsigned long, unsigned long, const void*) {
- /* Nonmatching */
+ return result;
}
-/* 802B7F04-802B7F30 .text getFsResource__12JKRFileCacheFPCc */
-void JKRFileCache::getFsResource(const char*) {
- /* Nonmatching */
-}
+/* 802B7D58-802B7E60 .text getDvdPathName__12JKRFileCacheCFPCc */
+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);
+ }
-/* 802B7F30-802B7F5C .text getNameResource__12JKRFileCacheFUlPCc */
-void JKRFileCache::getNameResource(unsigned long, const char*) {
- /* Nonmatching */
+ convStrLower(newPath);
+ return newPath;
}
-/* 802B7F5C-802B7F88 .text readFsResource__12JKRFileCacheFPvUlPCc */
-void JKRFileCache::readFsResource(void*, unsigned long, const char*) {
- /* Nonmatching */
+/* 802B7E60-802B7EA8 .text convStrLower__12JKRFileCacheCFPc */
+void JKRFileCache::convStrLower(char* buffer) const {
+ while (*buffer) {
+ *buffer++ = tolower(*buffer);
+ }
}
-/* 802B7F88-802B7FB4 .text readNameResource__12JKRFileCacheFPvUlUlPCc */
-void JKRFileCache::readNameResource(void*, unsigned long, unsigned long, const char*) {
- /* Nonmatching */
+/* 802B7EA8-802B7F04 .text __ct__Q212JKRFileCache11CCacheBlockFUlUlPCv */
+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
}