From 9c5ad440003ad30e75af4659de6bb4db8c8c82bf Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 2 Nov 2014 19:50:26 -0800 Subject: [PATCH] Add an interface to read multiple blocks at once. --- Core/FileSystems/BlockDevices.h | 9 +++++ Core/FileSystems/ISOFileSystem.cpp | 60 ++++++++++++++++-------------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index a482acb4a4..fd31d96e4b 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -31,6 +31,15 @@ class BlockDevice public: virtual ~BlockDevice() {} virtual bool ReadBlock(int blockNumber, u8 *outPtr) = 0; + virtual bool ReadBlocks(int minBlock, int count, u8 *outPtr) { + for (int b = 0; b < count; ++b) { + if (!ReadBlock(minBlock + b, outPtr)) { + return false; + } + outPtr += GetBlockSize(); + } + return true; + } int GetBlockSize() const { return 2048;} // forced, it cannot be changed by subclasses virtual u32 GetNumBlocks() = 0; }; diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index b7ab43b11b..3af5f403e5 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "Common/Common.h" #include "Common/CommonTypes.h" @@ -494,10 +495,10 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd u32 size = (u32)desc.pathTableLengthLE; u8 *out = Memory::GetPointer(outdataPtr); - while (size >= 2048) { - blockDevice->ReadBlock(block++, out); - out += 2048; - } + int blocks = size / blockDevice->GetBlockSize(); + blockDevice->ReadBlocks(block, blocks, out); + size -= blocks * blockDevice->GetBlockSize(); + out += blocks * blockDevice->GetBlockSize(); // The remaining (or, usually, only) partial sector. if (size > 0) { @@ -527,12 +528,9 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) if (e.isBlockSectorMode) { // Whole sectors! Shortcut to this simple code. - for (int i = 0; i < size; i++) - { - blockDevice->ReadBlock(e.seekPos, pointer + i * 2048); - e.seekPos++; - } - return (size_t)size; + blockDevice->ReadBlocks(e.seekPos, (int)size, pointer); + e.seekPos += (int)size; + return (int)size; } u32 positionOnIso; @@ -559,29 +557,37 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) } //okay, we have size and position, let's rock - u32 totalRead = 0; + const int firstBlockOffset = positionOnIso & 2047; + const int firstBlockSize = firstBlockOffset == 0 ? 0 : (int)std::min(size, 2048LL - firstBlockOffset); + const int lastBlockSize = (size - firstBlockSize) & 2047; + const s64 middleSize = size - firstBlockSize - lastBlockSize; int secNum = positionOnIso / 2048; - int posInSector = positionOnIso & 2047; - s64 remain = size; - u8 theSector[2048]; - while (remain > 0) - { - blockDevice->ReadBlock(secNum, theSector); - size_t bytesToCopy = 2048 - posInSector; - if ((s64)bytesToCopy > remain) - bytesToCopy = (size_t)remain; + _dbg_assert_msg_(FILESYS, (middleSize & 2047) == 0, "Remaining size should be aligned"); - memcpy(pointer, theSector + posInSector, bytesToCopy); - totalRead += (u32)bytesToCopy; - pointer += bytesToCopy; - remain -= bytesToCopy; - posInSector = 0; - secNum++; + if (firstBlockSize != 0) + { + blockDevice->ReadBlock(secNum++, theSector); + memcpy(pointer, theSector + firstBlockOffset, firstBlockSize); + pointer += firstBlockSize; } + if (middleSize != 0) + { + const u32 sectors = (u32)(middleSize / 2048); + blockDevice->ReadBlocks(secNum, sectors, pointer); + secNum += sectors; + pointer += middleSize; + } + if (lastBlockSize != 0) + { + blockDevice->ReadBlock(secNum++, theSector); + memcpy(pointer, theSector, lastBlockSize); + pointer += lastBlockSize; + } + e.seekPos += (unsigned int)size; - return totalRead; + return (size_t)size; } else {