diff options
Diffstat (limited to 'src/JSystem/JHostIO/JORFile.cpp')
| -rw-r--r-- | src/JSystem/JHostIO/JORFile.cpp | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/src/JSystem/JHostIO/JORFile.cpp b/src/JSystem/JHostIO/JORFile.cpp new file mode 100644 index 0000000000..94a1979443 --- /dev/null +++ b/src/JSystem/JHostIO/JORFile.cpp @@ -0,0 +1,182 @@ +#include "JSystem/JHostIO/JORFile.h" +#include "JSystem/JHostIO/JORServer.h" +#include <dolphin.h> + +JORFile::JORFile() +: mHandle(0), + mFileLength(0), + mStatus(EStatus_WAIT), + mNFileName(0), + field_0x18(0) {} + +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; +} + +// NONMATCHING, equivalent? +void JORFile::close() { + if (mHandle != 0) { + mStatus = EStatus_WAIT; + JORMContext* 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; +} |
