summaryrefslogtreecommitdiff
path: root/libs/JSystem/src/JHostIO/JORFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/JSystem/src/JHostIO/JORFile.cpp')
-rw-r--r--libs/JSystem/src/JHostIO/JORFile.cpp189
1 files changed, 189 insertions, 0 deletions
diff --git a/libs/JSystem/src/JHostIO/JORFile.cpp b/libs/JSystem/src/JHostIO/JORFile.cpp
new file mode 100644
index 0000000000..f689f06534
--- /dev/null
+++ b/libs/JSystem/src/JHostIO/JORFile.cpp
@@ -0,0 +1,189 @@
+#include "JSystem/JSystem.h" // IWYU pragma: keep
+
+#include "JSystem/JHostIO/JORFile.h"
+#include "JSystem/JHostIO/JORServer.h"
+#ifdef __REVOLUTION_SDK__
+#include <revolution.h>
+#else
+#include <dolphin.h>
+#endif
+
+JORFile::JORFile()
+: mHandle(0),
+ mFileLength(0),
+ mStatus(EStatus_WAIT),
+ mNFileName(0),
+ field_0x18(0),
+ mDataStream() {}
+
+int JORFile::countMaskSize(const char* mask) {
+ u32 var_r28 = 0;
+ u32 var_r30 = 0;
+
+ while (true) {
+ u32 var_r27 = var_r30;
+
+ while (mask[var_r30] != 0) {
+ var_r30++;
+ if (var_r30 - var_r27 > 0xFF) {
+ return 0;
+ }
+ }
+
+ var_r30++;
+ while (mask[var_r30] != 0) {
+ var_r30++;
+ if (var_r30 - var_r27 > 0xFF) {
+ return 0;
+ }
+ }
+
+ var_r30++;
+ if (mask[var_r30] == 0) {
+ return var_r30 + 1;
+ }
+
+ var_r28++;
+ if (var_r28 > 0x28) {
+ return 0;
+ }
+ }
+}
+
+void JORFile::waitMessage_() {
+ while (mStatus == EStatus_WAIT) {
+ JOR_MESSAGELOOP();
+ }
+}
+
+int JORFile::open(const char* path, u32 flags, const char* extMask, const char* defaultExt, const char* param_4, const char* fileSuffix) {
+ if (mHandle != 0) {
+ return 0;
+ }
+
+ mStatus = EStatus_WAIT;
+ mFlags = flags;
+
+ if (extMask == NULL) {
+ extMask = "";
+ }
+
+ u32 mask_size = countMaskSize(extMask);
+ JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO);
+ mctx->openFile(this, mFlags, path, extMask, mask_size, defaultExt, param_4, fileSuffix);
+ JORServer::getInstance()->releaseMCTX(mctx);
+
+ waitMessage_();
+
+ if (mHandle == 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+void JORFile::close() {
+ JORMContext* mctx;
+ if (mHandle != 0) {
+ mStatus = EStatus_WAIT;
+ mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO);
+ mctx->closeFile(this);
+ JORServer::getInstance()->releaseMCTX(mctx);
+
+ waitMessage_();
+ mHandle = 0;
+ }
+}
+
+void JORFile::readBegin_(s32 len) {
+ mStatus = EStatus_WAIT;
+ JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO);
+ mctx->readBegin(this, len);
+ JORServer::getInstance()->releaseMCTX(mctx);
+
+ waitMessage_();
+}
+
+void JORFile::readLoop_() {
+ mStatus = EStatus_WAIT;
+ JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO);
+ mctx->readData(this);
+ JORServer::getInstance()->releaseMCTX(mctx);
+
+ waitMessage_();
+}
+
+s32 JORFile::readData(void* buffer, s32 length) {
+ if (mHandle == 0) {
+ return 0;
+ }
+
+ s32 len = length == 0 ? mFileLength : length;
+ setBuffer(buffer, len);
+ readBegin_(len);
+
+ do {
+ readLoop_();
+ if (mStatus == EStatus_READ_BEGIN) {
+ setBuffer(NULL, 0);
+ return 0;
+ }
+ } while (mStatus != EStatus_WRITE_END);
+
+ setBuffer(NULL, 0);
+ DCFlushRange(buffer, len);
+ return len;
+}
+
+void JORFile::setBuffer(void* buffer, s32 length) {
+ mDataStream.setBuffer(buffer, length);
+}
+
+void JORFile::writeBegin_(s32 len) {
+ mStatus = EStatus_WAIT;
+ JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO);
+ mctx->writeBegin(this, mFlags, len);
+ JORServer::getInstance()->releaseMCTX(mctx);
+
+ waitMessage_();
+}
+
+void JORFile::writeLoop_(const void* pBuffer, s32 size, u32 pos) {
+ mStatus = EStatus_WAIT;
+ JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO);
+ mctx->writeData(this, pBuffer, size, pos);
+ JORServer::getInstance()->releaseMCTX(mctx);
+
+ waitMessage_();
+}
+
+void JORFile::writeDone_(s32 len) {
+ mStatus = EStatus_WAIT;
+ JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO);
+ mctx->writeDone(this, len);
+ JORServer::getInstance()->releaseMCTX(mctx);
+
+ waitMessage_();
+}
+
+s32 JORFile::writeData(const void* buffer, s32 length) {
+ if (mHandle == 0) {
+ return 0;
+ }
+
+ s32 len = length == 0 ? mFileLength : length;
+ writeBegin_(len);
+
+ u32 pos = 0;
+ s32 size = 0;
+ u8* buf_start = (u8*)buffer;
+ do {
+ size = len - pos > 0xF00 ? 0xF00 : len - pos;
+ writeLoop_(buf_start + pos, size, pos);
+
+ pos += size;
+ } while (len - pos != 0);
+
+ writeDone_(len);
+ return len;
+}