Shared NFS data class not necessary

This commit is contained in:
Jack Andersen 2019-11-24 13:47:48 -10:00
parent 19604b2a3b
commit 48a2981a93
4 changed files with 139 additions and 143 deletions

View File

@ -54,14 +54,21 @@
namespace nod { namespace nod {
/* define our own min/max to avoid MSVC BS */ /* define our own min/max to avoid MSVC BS */
template <typename T> template <typename T>
inline T min(T a, T b) { constexpr T min(T a, T b) {
return a < b ? a : b; return a < b ? a : b;
} }
template <typename T> template <typename T>
inline T max(T a, T b) { constexpr T max(T a, T b) {
return a > b ? a : b; return a > b ? a : b;
} }
/* template-based div for flexible typing and avoiding a library call */
template <typename T>
constexpr auto div(T a, T b) {
struct DivTp { T quot, rem; };
return DivTp{a / b, a % b};
}
/* Log Module */ /* Log Module */
extern logvisor::Module LogModule; extern logvisor::Module LogModule;

View File

@ -5,8 +5,6 @@
#include <logvisor/logvisor.hpp> #include <logvisor/logvisor.hpp>
#include <array>
namespace nod { namespace nod {
/* /*
@ -16,7 +14,6 @@ namespace nod {
*/ */
class DiscIONFS : public IDiscIO { class DiscIONFS : public IDiscIO {
struct DiscIONFSShared {
std::vector<std::unique_ptr<IFileIO>> files; std::vector<std::unique_ptr<IFileIO>> files;
struct NFSHead { struct NFSHead {
@ -46,7 +43,7 @@ class DiscIONFS : public IDiscIO {
}; };
FBO logicalToFBO(uint64_t offset) const { FBO logicalToFBO(uint64_t offset) const {
auto blockAndRemBytes = std::lldiv(offset, 0x8000); /* 32768 bytes per block */ auto blockAndRemBytes = nod::div(offset, uint64_t(0x8000)); /* 32768 bytes per block */
uint32_t block = UINT32_MAX; uint32_t block = UINT32_MAX;
for (uint32_t i = 0, physicalBlock = 0; i < nfsHead.lbaRangeCount; ++i) { for (uint32_t i = 0, physicalBlock = 0; i < nfsHead.lbaRangeCount; ++i) {
const auto& range = nfsHead.lbaRanges[i]; const auto& range = nfsHead.lbaRanges[i];
@ -59,12 +56,13 @@ class DiscIONFS : public IDiscIO {
/* This offset has no physical mapping, read zeroes */ /* This offset has no physical mapping, read zeroes */
if (block == UINT32_MAX) if (block == UINT32_MAX)
return {UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX}; return {UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX};
auto fileAndRemBlocks = std::lldiv(block, 8000); /* 8000 blocks per file */ auto fileAndRemBlocks = nod::div(block, uint32_t(8000)); /* 8000 blocks per file */
return {uint32_t(fileAndRemBlocks.quot), uint32_t(fileAndRemBlocks.rem), return {uint32_t(fileAndRemBlocks.quot), uint32_t(fileAndRemBlocks.rem),
uint32_t(blockAndRemBytes.quot), uint32_t(blockAndRemBytes.rem)}; uint32_t(blockAndRemBytes.quot), uint32_t(blockAndRemBytes.rem)};
} }
DiscIONFSShared(SystemStringView fpin, bool& err) { public:
DiscIONFS(SystemStringView fpin, bool& err) {
/* Validate file path format */ /* Validate file path format */
using SignedSize = std::make_signed<SystemString::size_type>::type; using SignedSize = std::make_signed<SystemString::size_type>::type;
const auto dotPos = SignedSize(fpin.rfind('.')); const auto dotPos = SignedSize(fpin.rfind('.'));
@ -133,20 +131,15 @@ class DiscIONFS : public IDiscIO {
} }
} }
} }
};
std::shared_ptr<DiscIONFSShared> m_shared;
public:
DiscIONFS(SystemStringView fpin, bool& err) : m_shared(std::make_shared<DiscIONFSShared>(fpin, err)) {}
class ReadStream : public IReadStream { class ReadStream : public IReadStream {
friend class DiscIONFS; friend class DiscIONFS;
std::shared_ptr<DiscIONFSShared> m_shared; const DiscIONFS& m_parent;
std::unique_ptr<IReadStream> m_rs; std::unique_ptr<IReadStream> m_rs;
std::unique_ptr<IAES> m_aes; std::unique_ptr<IAES> m_aes;
/* Physical address - all UINT32_MAX indicates logical zero block */ /* Physical address - all UINT32_MAX indicates logical zero block */
DiscIONFSShared::FBO m_physAddr; DiscIONFS::FBO m_physAddr;
/* Logical address */ /* Logical address */
uint64_t m_offset; uint64_t m_offset;
@ -156,24 +149,24 @@ public:
uint32_t m_curFile = UINT32_MAX; uint32_t m_curFile = UINT32_MAX;
uint32_t m_curBlock = UINT32_MAX; uint32_t m_curBlock = UINT32_MAX;
ReadStream(std::shared_ptr<DiscIONFSShared> shared, uint64_t offset, bool& err) ReadStream(const DiscIONFS& parent, uint64_t offset, bool& err)
: m_shared(std::move(shared)), m_aes(NewAES()), : m_parent(parent), m_aes(NewAES()),
m_physAddr({UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX}), m_offset(offset) { m_physAddr({UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX}), m_offset(offset) {
m_aes->setKey(m_shared->key); m_aes->setKey(m_parent.key);
setNewLogicalAddr(offset); setLogicalAddr(offset);
} }
uint8_t m_encBuf[0x8000] = {}; uint8_t m_encBuf[0x8000] = {};
uint8_t m_decBuf[0x8000] = {}; uint8_t m_decBuf[0x8000] = {};
void setCurFile(uint32_t curFile) { void setCurFile(uint32_t curFile) {
if (curFile >= m_shared->files.size()) { if (curFile >= m_parent.files.size()) {
LogModule.report(logvisor::Error, fmt("Out of bounds NFS file access")); LogModule.report(logvisor::Error, fmt("Out of bounds NFS file access"));
return; return;
} }
m_curFile = curFile; m_curFile = curFile;
m_curBlock = UINT32_MAX; m_curBlock = UINT32_MAX;
m_rs = m_shared->files[m_curFile]->beginReadStream(); m_rs = m_parent.files[m_curFile]->beginReadStream();
} }
void setCurBlock(uint32_t curBlock) { void setCurBlock(uint32_t curBlock) {
@ -181,7 +174,7 @@ public:
m_rs->seek(m_curBlock * 0x8000 + 0x200); m_rs->seek(m_curBlock * 0x8000 + 0x200);
} }
void setNewPhysicalAddr(DiscIONFSShared::FBO physAddr) { void setPhysicalAddr(DiscIONFS::FBO physAddr) {
/* If we're just changing the offset, nothing else needs to be done */ /* If we're just changing the offset, nothing else needs to be done */
if (m_physAddr.file == physAddr.file && m_physAddr.block == physAddr.block) { if (m_physAddr.file == physAddr.file && m_physAddr.block == physAddr.block) {
m_physAddr.offset = physAddr.offset; m_physAddr.offset = physAddr.offset;
@ -217,9 +210,7 @@ public:
m_aes->decrypt((const uint8_t*)ivBuf, m_encBuf, m_decBuf, 0x8000); m_aes->decrypt((const uint8_t*)ivBuf, m_encBuf, m_decBuf, 0x8000);
} }
void setNewLogicalAddr(uint64_t addr) { void setLogicalAddr(uint64_t addr) { setPhysicalAddr(m_parent.logicalToFBO(m_offset)); }
setNewPhysicalAddr(m_shared->logicalToFBO(m_offset));
}
public: public:
uint64_t read(void* buf, uint64_t length) override { uint64_t read(void* buf, uint64_t length) override {
@ -237,7 +228,7 @@ public:
dst += readSize; dst += readSize;
rem -= readSize; rem -= readSize;
m_offset += readSize; m_offset += readSize;
setNewLogicalAddr(m_offset); setLogicalAddr(m_offset);
} }
return dst - (uint8_t*)buf; return dst - (uint8_t*)buf;
@ -250,13 +241,13 @@ public:
m_offset += offset; m_offset += offset;
else else
return; return;
setNewLogicalAddr(m_offset); setLogicalAddr(m_offset);
} }
}; };
std::unique_ptr<IReadStream> beginReadStream(uint64_t offset) const override { std::unique_ptr<IReadStream> beginReadStream(uint64_t offset) const override {
bool err = false; bool err = false;
auto ret = std::unique_ptr<IReadStream>(new ReadStream(m_shared, offset, err)); auto ret = std::unique_ptr<IReadStream>(new ReadStream(*this, offset, err));
if (err) if (err)
return {}; return {};

View File

@ -373,7 +373,7 @@ public:
} }
uint64_t position() const override { return m_offset; } uint64_t position() const override { return m_offset; }
uint64_t read(void* buf, uint64_t length) override { uint64_t read(void* buf, uint64_t length) override {
auto blockAndRemOff = std::lldiv(m_offset, 0x7c00); auto blockAndRemOff = nod::div(m_offset, uint64_t(0x7c00));
uint64_t rem = length; uint64_t rem = length;
uint8_t* dst = (uint8_t*)buf; uint8_t* dst = (uint8_t*)buf;
@ -1239,7 +1239,7 @@ std::optional<uint64_t> DiscBuilderWii::CalculateTotalSizeRequired(SystemStringV
std::optional<uint64_t> sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, true); std::optional<uint64_t> sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeBuild(dirIn, PartitionKind::Data, true);
if (!sz) if (!sz)
return sz; return sz;
auto szDiv = std::lldiv(*sz, 0x1F0000); auto szDiv = nod::div(*sz, uint64_t(0x1F0000));
if (szDiv.rem) if (szDiv.rem)
++szDiv.quot; ++szDiv.quot;
sz = szDiv.quot * 0x200000; sz = szDiv.quot * 0x200000;
@ -1346,7 +1346,7 @@ std::optional<uint64_t> DiscMergerWii::CalculateTotalSizeRequired(DiscWii& sourc
std::optional<uint64_t> sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(sourceDisc.getDataPartition(), dirIn); std::optional<uint64_t> sz = DiscBuilderBase::PartitionBuilderBase::CalculateTotalSizeMerge(sourceDisc.getDataPartition(), dirIn);
if (!sz) if (!sz)
return std::nullopt; return std::nullopt;
auto szDiv = std::lldiv(*sz, 0x1F0000); auto szDiv = nod::div(*sz, uint64_t(0x1F0000));
if (szDiv.rem) if (szDiv.rem)
++szDiv.quot; ++szDiv.quot;
sz = szDiv.quot * 0x200000; sz = szDiv.quot * 0x200000;

View File

@ -68,16 +68,14 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(SystemStringView path, bool& isWii)
std::unique_ptr<DiscBase> ret; std::unique_ptr<DiscBase> ret;
if (isWii) { if (isWii) {
ret = std::make_unique<DiscWii>(std::move(discIO), err); ret = std::make_unique<DiscWii>(std::move(discIO), err);
if (err) { if (err)
return nullptr; return {};
}
return ret; return ret;
} }
ret = std::make_unique<DiscGCN>(std::move(discIO), err); ret = std::make_unique<DiscGCN>(std::move(discIO), err);
if (err) { if (err)
return nullptr; return {};
}
return ret; return ret;
} }