mirror of https://github.com/AxioDL/nod.git
Add floating point progress to builder callbacks
This commit is contained in:
parent
e494dbba9f
commit
dd20c1d255
|
@ -40,7 +40,7 @@ int main(int argc, char* argv[])
|
|||
logvisor::RegisterConsoleLogger();
|
||||
|
||||
nod::ExtractionContext ctx = { true, true, [&](const std::string& str, float c){
|
||||
fprintf(stderr, "Current node: %s, Extraction %g%% Complete\n", str.c_str(), c);
|
||||
fprintf(stderr, "Current node: %s, Extraction %g%% Complete\n", str.c_str(), c * 100.f);
|
||||
}};
|
||||
const nod::SystemChar* inDir = nullptr;
|
||||
const nod::SystemChar* outDir = _S(".");
|
||||
|
@ -58,18 +58,13 @@ int main(int argc, char* argv[])
|
|||
outDir = argv[a];
|
||||
}
|
||||
|
||||
size_t lastIdx = -1;
|
||||
auto progFunc = [&](size_t idx, const nod::SystemString& name, size_t bytes)
|
||||
auto progFunc = [&](float prog, const nod::SystemString& name, size_t bytes)
|
||||
{
|
||||
if (idx != lastIdx)
|
||||
{
|
||||
lastIdx = idx;
|
||||
printf("\n");
|
||||
}
|
||||
nod::Printf(_S("\r "));
|
||||
if (bytes != -1)
|
||||
nod::Printf(_S("\r%s %" PRISize " B"), name.c_str(), bytes);
|
||||
nod::Printf(_S("\r%g%% %s %" PRISize " B"), prog * 100.f, name.c_str(), bytes);
|
||||
else
|
||||
nod::Printf(_S("\r%s"), name.c_str());
|
||||
nod::Printf(_S("\r%g%% %s"), prog * 100.f, name.c_str());
|
||||
fflush(stdout);
|
||||
};
|
||||
|
||||
|
@ -135,7 +130,7 @@ int main(int argc, char* argv[])
|
|||
if (nod::DiscBuilderGCN::CalculateTotalSizeRequired(argv[4], argv[5]) == -1)
|
||||
return 1;
|
||||
|
||||
bool ret;
|
||||
nod::EBuildResult ret;
|
||||
|
||||
if (argc < 8)
|
||||
{
|
||||
|
@ -151,7 +146,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
printf("\n");
|
||||
if (!ret)
|
||||
if (ret != nod::EBuildResult::Success)
|
||||
return 1;
|
||||
}
|
||||
else if (!strcasecmp(argv[1], _S("makewii")))
|
||||
|
@ -202,7 +197,7 @@ int main(int argc, char* argv[])
|
|||
if (nod::DiscBuilderWii::CalculateTotalSizeRequired(argv[4], argv[5], dual) == -1)
|
||||
return 1;
|
||||
|
||||
bool ret;
|
||||
nod::EBuildResult ret;
|
||||
|
||||
if (argc < 9)
|
||||
{
|
||||
|
@ -218,7 +213,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
printf("\n");
|
||||
if (!ret)
|
||||
if (ret != nod::EBuildResult::Success)
|
||||
return 1;
|
||||
}
|
||||
else if (!strcasecmp(argv[1], _S("mergegcn")))
|
||||
|
@ -252,7 +247,7 @@ int main(int argc, char* argv[])
|
|||
if (nod::DiscMergerGCN::CalculateTotalSizeRequired(static_cast<nod::DiscGCN&>(*disc), argv[2]) == -1)
|
||||
return 1;
|
||||
|
||||
bool ret;
|
||||
nod::EBuildResult ret;
|
||||
|
||||
if (argc < 5)
|
||||
{
|
||||
|
@ -268,7 +263,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
printf("\n");
|
||||
if (!ret)
|
||||
if (ret != nod::EBuildResult::Success)
|
||||
return 1;
|
||||
}
|
||||
else if (!strcasecmp(argv[1], _S("mergewii")))
|
||||
|
@ -303,7 +298,7 @@ int main(int argc, char* argv[])
|
|||
if (nod::DiscMergerWii::CalculateTotalSizeRequired(static_cast<nod::DiscWii&>(*disc), argv[2], dual) == -1)
|
||||
return 1;
|
||||
|
||||
bool ret;
|
||||
nod::EBuildResult ret;
|
||||
|
||||
if (argc < 5)
|
||||
{
|
||||
|
@ -319,7 +314,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
printf("\n");
|
||||
if (!ret)
|
||||
if (ret != nod::EBuildResult::Success)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -15,7 +15,14 @@
|
|||
namespace nod
|
||||
{
|
||||
|
||||
using FProgress = std::function<void(size_t, const SystemString&, size_t)>;
|
||||
using FProgress = std::function<void(float totalProg, const SystemString& fileName, size_t fileBytesXfered)>;
|
||||
|
||||
enum class EBuildResult
|
||||
{
|
||||
Success,
|
||||
Failed,
|
||||
DiskFull
|
||||
};
|
||||
|
||||
class FSTNode
|
||||
{
|
||||
|
@ -237,6 +244,18 @@ public:
|
|||
uint64_t m_offset;
|
||||
public:
|
||||
mutable size_t m_curNodeIdx = 0;
|
||||
float getProgressFactor() const { return getNodeCount() ? m_curNodeIdx / float(getNodeCount()) : 0.f; }
|
||||
float getProgressFactorMidFile(size_t curByte, size_t totalBytes) const
|
||||
{
|
||||
if (!getNodeCount())
|
||||
return 0.f;
|
||||
|
||||
if (totalBytes)
|
||||
return (m_curNodeIdx + (curByte / float(totalBytes))) / float(getNodeCount());
|
||||
else
|
||||
return m_curNodeIdx / float(getNodeCount());
|
||||
}
|
||||
|
||||
IPartition(const DiscBase& parent, Kind kind, uint64_t offset)
|
||||
: m_parent(parent), m_kind(kind), m_offset(offset) {}
|
||||
virtual uint64_t normalizeOffset(uint64_t anOffset) const {return anOffset;}
|
||||
|
@ -342,18 +361,25 @@ public:
|
|||
size_t m_buildNameOff = 0;
|
||||
virtual uint64_t userAllocate(uint64_t reqSz, IPartWriteStream& ws)=0;
|
||||
virtual uint32_t packOffset(uint64_t offset) const=0;
|
||||
|
||||
void recursiveBuildNodesPre(const SystemChar* dirIn, uint64_t dolInode);
|
||||
bool recursiveBuildNodes(IPartWriteStream& ws, bool system, const SystemChar* dirIn, uint64_t dolInode);
|
||||
|
||||
bool recursiveBuildFST(const SystemChar* dirIn, uint64_t dolInode,
|
||||
std::function<void(void)> incParents);
|
||||
|
||||
void recursiveMergeNodesPre(const DiscBase::IPartition::Node* nodeIn, const SystemChar* dirIn);
|
||||
bool recursiveMergeNodes(IPartWriteStream& ws, bool system,
|
||||
const DiscBase::IPartition::Node* nodeIn, const SystemChar* dirIn,
|
||||
const SystemString& keyPath);
|
||||
bool recursiveMergeFST(const DiscBase::IPartition::Node* nodeIn,
|
||||
const SystemChar* dirIn, std::function<void(void)> incParents,
|
||||
const SystemString& keyPath);
|
||||
|
||||
static bool RecursiveCalculateTotalSize(uint64_t& totalSz,
|
||||
const DiscBase::IPartition::Node* nodeIn,
|
||||
const SystemChar* dirIn);
|
||||
|
||||
void addBuildName(const SystemString& str)
|
||||
{
|
||||
SystemUTF8View utf8View(str);
|
||||
|
@ -396,11 +422,26 @@ protected:
|
|||
std::vector<std::unique_ptr<PartitionBuilderBase>> m_partitions;
|
||||
int64_t m_discCapacity;
|
||||
public:
|
||||
std::function<void(size_t idx, const SystemString&, size_t)> m_progressCB;
|
||||
FProgress m_progressCB;
|
||||
size_t m_progressIdx = 0;
|
||||
size_t m_progressTotal = 0;
|
||||
float getProgressFactor() const
|
||||
{
|
||||
return m_progressTotal ? std::min(1.f, m_progressIdx / float(m_progressTotal)) : 0.f;
|
||||
}
|
||||
float getProgressFactorMidFile(size_t curByte, size_t totalBytes) const
|
||||
{
|
||||
if (!m_progressTotal)
|
||||
return 0.f;
|
||||
|
||||
if (totalBytes)
|
||||
return (m_progressIdx + (curByte / float(totalBytes))) / float(m_progressTotal);
|
||||
else
|
||||
return m_progressIdx / float(m_progressTotal);
|
||||
}
|
||||
|
||||
virtual ~DiscBuilderBase() = default;
|
||||
DiscBuilderBase(const SystemChar* outPath, int64_t discCapacity,
|
||||
std::function<void(size_t idx, const SystemString&, size_t)> progressCB)
|
||||
DiscBuilderBase(const SystemChar* outPath, int64_t discCapacity, FProgress progressCB)
|
||||
: m_outPath(outPath), m_fileIO(NewFileIO(outPath, discCapacity)),
|
||||
m_discCapacity(discCapacity), m_progressCB(progressCB) {}
|
||||
DiscBuilderBase(DiscBuilderBase&&) = default;
|
||||
|
|
|
@ -21,8 +21,8 @@ class DiscBuilderGCN : public DiscBuilderBase
|
|||
public:
|
||||
DiscBuilderGCN(const SystemChar* outPath, const char gameID[6], const char* gameTitle,
|
||||
uint32_t fstMemoryAddr, FProgress progressCB);
|
||||
bool buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn,
|
||||
const SystemChar* apploaderIn);
|
||||
EBuildResult buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn,
|
||||
const SystemChar* apploaderIn);
|
||||
static uint64_t CalculateTotalSizeRequired(const SystemChar* dirIn, const SystemChar* dolIn);
|
||||
};
|
||||
|
||||
|
@ -32,7 +32,7 @@ class DiscMergerGCN
|
|||
DiscBuilderGCN m_builder;
|
||||
public:
|
||||
DiscMergerGCN(const SystemChar* outPath, DiscGCN& sourceDisc, FProgress progressCB);
|
||||
bool mergeFromDirectory(const SystemChar* dirIn);
|
||||
EBuildResult mergeFromDirectory(const SystemChar* dirIn);
|
||||
static uint64_t CalculateTotalSizeRequired(DiscGCN& sourceDisc, const SystemChar* dirIn);
|
||||
};
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@ class DiscBuilderWii : public DiscBuilderBase
|
|||
public:
|
||||
DiscBuilderWii(const SystemChar* outPath, const char gameID[6], const char* gameTitle,
|
||||
bool dualLayer, FProgress progressCB);
|
||||
bool buildFromDirectory(const SystemChar* dirIn,
|
||||
const SystemChar* dolIn,
|
||||
const SystemChar* apploaderIn,
|
||||
const SystemChar* partHeadIn);
|
||||
EBuildResult buildFromDirectory(const SystemChar* dirIn,
|
||||
const SystemChar* dolIn,
|
||||
const SystemChar* apploaderIn,
|
||||
const SystemChar* partHeadIn);
|
||||
static uint64_t CalculateTotalSizeRequired(const SystemChar* dirIn, const SystemChar* dolIn,
|
||||
bool& dualLayer);
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ class DiscMergerWii
|
|||
public:
|
||||
DiscMergerWii(const SystemChar* outPath, DiscWii& sourceDisc,
|
||||
bool dualLayer, FProgress progressCB);
|
||||
bool mergeFromDirectory(const SystemChar* dirIn);
|
||||
EBuildResult mergeFromDirectory(const SystemChar* dirIn);
|
||||
static uint64_t CalculateTotalSizeRequired(DiscWii& sourceDisc, const SystemChar* dirIn,
|
||||
bool& dualLayer);
|
||||
};
|
||||
|
|
|
@ -20,7 +20,55 @@ public:
|
|||
{
|
||||
virtual ~IWriteStream() {}
|
||||
virtual uint64_t write(const void* buf, uint64_t length)=0;
|
||||
virtual uint64_t copyFromDisc(struct IPartReadStream& discio, uint64_t length)=0;
|
||||
|
||||
uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length)
|
||||
{
|
||||
uint64_t read = 0;
|
||||
uint8_t buf[0x7c00];
|
||||
while (length)
|
||||
{
|
||||
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
||||
uint64_t readSz = discio.read(buf, thisSz);
|
||||
if (thisSz != readSz)
|
||||
{
|
||||
LogModule.report(logvisor::Error, "unable to read enough from disc");
|
||||
return read;
|
||||
}
|
||||
if (write(buf, readSz) != readSz)
|
||||
{
|
||||
LogModule.report(logvisor::Error, "unable to write in file");
|
||||
return read;
|
||||
}
|
||||
length -= thisSz;
|
||||
read += thisSz;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length, const std::function<void(float)>& prog)
|
||||
{
|
||||
uint64_t read = 0;
|
||||
uint8_t buf[0x7c00];
|
||||
uint64_t total = length;
|
||||
while (length)
|
||||
{
|
||||
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
||||
uint64_t readSz = discio.read(buf, thisSz);
|
||||
if (thisSz != readSz)
|
||||
{
|
||||
LogModule.report(logvisor::Error, "unable to read enough from disc");
|
||||
return read;
|
||||
}
|
||||
if (write(buf, readSz) != readSz)
|
||||
{
|
||||
LogModule.report(logvisor::Error, "unable to write in file");
|
||||
return read;
|
||||
}
|
||||
length -= thisSz;
|
||||
read += thisSz;
|
||||
prog(read / float(total));
|
||||
}
|
||||
return read;
|
||||
}
|
||||
};
|
||||
virtual std::unique_ptr<IWriteStream> beginWriteStream() const=0;
|
||||
virtual std::unique_ptr<IWriteStream> beginWriteStream(uint64_t offset) const=0;
|
||||
|
|
132
lib/DiscBase.cpp
132
lib/DiscBase.cpp
|
@ -99,7 +99,7 @@ bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath
|
|||
{
|
||||
++m_parent.m_curNodeIdx;
|
||||
if (ctx.verbose && ctx.progressCB && !getName().empty())
|
||||
ctx.progressCB(getName(), float(m_parent.m_curNodeIdx * 100.f) / m_parent.getNodeCount());
|
||||
ctx.progressCB(getName(), m_parent.m_curNodeIdx / float(m_parent.getNodeCount()));
|
||||
if (Mkdir(path.c_str(), 0755) && errno != EEXIST)
|
||||
{
|
||||
LogModule.report(logvisor::Error, _S("unable to mkdir '%s'"), path.c_str());
|
||||
|
@ -112,9 +112,8 @@ bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath
|
|||
else if (m_kind == Kind::File)
|
||||
{
|
||||
Sstat theStat;
|
||||
++m_parent.m_curNodeIdx;
|
||||
if (ctx.verbose && ctx.progressCB)
|
||||
ctx.progressCB(getName(), float(m_parent.m_curNodeIdx * 100.f) / m_parent.getNodeCount());
|
||||
ctx.progressCB(getName(), m_parent.m_curNodeIdx / float(m_parent.getNodeCount()));
|
||||
|
||||
if (ctx.force || Stat(path.c_str(), &theStat))
|
||||
{
|
||||
|
@ -122,8 +121,14 @@ bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath
|
|||
std::unique_ptr<IFileIO::IWriteStream> ws = NewFileIO(path)->beginWriteStream();
|
||||
if (!rs || !ws)
|
||||
return false;
|
||||
ws->copyFromDisc(*rs, m_discLength);
|
||||
ws->copyFromDisc(*rs, m_discLength,
|
||||
[&](float prog)
|
||||
{
|
||||
if (ctx.verbose && ctx.progressCB)
|
||||
ctx.progressCB(getName(), (m_parent.m_curNodeIdx + prog) / float(m_parent.getNodeCount()));
|
||||
});
|
||||
}
|
||||
++m_parent.m_curNodeIdx;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -263,6 +268,26 @@ static size_t PatchDOL(IFileIO::IReadStream& in, IPartWriteStream& out, size_t s
|
|||
return out.write(buf.get(), sz);
|
||||
}
|
||||
|
||||
void DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodesPre(const SystemChar* dirIn,
|
||||
uint64_t dolInode)
|
||||
{
|
||||
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||
{
|
||||
if (e.m_isDir)
|
||||
{
|
||||
recursiveBuildNodesPre(e.m_path.c_str(), dolInode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dolInode == GetInode(e.m_path.c_str()))
|
||||
continue;
|
||||
|
||||
++m_parent.m_progressTotal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodes(IPartWriteStream& ws,
|
||||
bool system,
|
||||
const SystemChar* dirIn,
|
||||
|
@ -299,12 +324,12 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodes(IPartWriteStream
|
|||
{
|
||||
bool patched;
|
||||
xferSz = PatchDOL(*rs, ws, e.m_fileSz, patched);
|
||||
m_parent.m_progressCB(++m_parent.m_progressIdx, e.m_name + (patched ? _S(" [PATCHED]") : _S("")), xferSz);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), e.m_name + (patched ? _S(" [PATCHED]") : _S("")), xferSz);
|
||||
++m_parent.m_progressIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[0x8000];
|
||||
++m_parent.m_progressIdx;
|
||||
while (xferSz < e.m_fileSz)
|
||||
{
|
||||
size_t rdSz = rs->read(buf, nod::min(size_t(0x8000ul), e.m_fileSz - xferSz));
|
||||
|
@ -312,8 +337,9 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildNodes(IPartWriteStream
|
|||
break;
|
||||
ws.write(buf, rdSz);
|
||||
xferSz += rdSz;
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, e.m_name, xferSz);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactorMidFile(xferSz, e.m_fileSz), e.m_name, xferSz);
|
||||
}
|
||||
++m_parent.m_progressIdx;
|
||||
}
|
||||
for (size_t i=0 ; i<fileSz-xferSz ; ++i)
|
||||
ws.write("\xff", 1);
|
||||
|
@ -358,6 +384,64 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveBuildFST(const SystemChar*
|
|||
return true;
|
||||
}
|
||||
|
||||
void DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodesPre(const DiscBase::IPartition::Node* nodeIn,
|
||||
const SystemChar* dirIn)
|
||||
{
|
||||
/* Build map of existing nodes to write-through later */
|
||||
std::unordered_map<std::string, const Partition::Node*> fileNodes;
|
||||
std::unordered_map<std::string, const Partition::Node*> dirNodes;
|
||||
if (nodeIn)
|
||||
{
|
||||
fileNodes.reserve(nodeIn->size());
|
||||
dirNodes.reserve(nodeIn->size());
|
||||
for (const Partition::Node& ch : *nodeIn)
|
||||
{
|
||||
if (ch.getKind() == Partition::Node::Kind::File)
|
||||
fileNodes.insert(std::make_pair(ch.getName(), &ch));
|
||||
else if (ch.getKind() == Partition::Node::Kind::Directory)
|
||||
dirNodes.insert(std::make_pair(ch.getName(), &ch));
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge this directory's files */
|
||||
if (dirIn)
|
||||
{
|
||||
DirectoryEnumerator dEnum(dirIn, DirectoryEnumerator::Mode::DirsThenFilesSorted, false, false, true);
|
||||
for (const DirectoryEnumerator::Entry& e : dEnum)
|
||||
{
|
||||
SystemUTF8View nameView(e.m_name);
|
||||
|
||||
if (e.m_isDir)
|
||||
{
|
||||
auto search = dirNodes.find(nameView.utf8_str());
|
||||
if (search != dirNodes.cend())
|
||||
{
|
||||
recursiveMergeNodesPre(search->second, e.m_path.c_str());
|
||||
dirNodes.erase(search);
|
||||
}
|
||||
else
|
||||
{
|
||||
recursiveMergeNodesPre(nullptr, e.m_path.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileNodes.erase(nameView.utf8_str());
|
||||
++m_parent.m_progressTotal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write-through remaining dir nodes */
|
||||
for (const auto& p : dirNodes)
|
||||
{
|
||||
recursiveMergeNodesPre(p.second, nullptr);
|
||||
}
|
||||
|
||||
/* Write-through remaining file nodes */
|
||||
m_parent.m_progressTotal += fileNodes.size();
|
||||
}
|
||||
|
||||
bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream& ws,
|
||||
bool system,
|
||||
const DiscBase::IPartition::Node* nodeIn,
|
||||
|
@ -426,13 +510,13 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||
{
|
||||
bool patched;
|
||||
xferSz = PatchDOL(*rs, ws, e.m_fileSz, patched);
|
||||
m_parent.m_progressCB(++m_parent.m_progressIdx, e.m_name +
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), e.m_name +
|
||||
(patched ? _S(" [PATCHED]") : _S("")), xferSz);
|
||||
++m_parent.m_progressIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[0x8000];
|
||||
++m_parent.m_progressIdx;
|
||||
while (xferSz < e.m_fileSz)
|
||||
{
|
||||
size_t rdSz = rs->read(buf, nod::min(size_t(0x8000ul), e.m_fileSz - xferSz));
|
||||
|
@ -440,8 +524,9 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||
break;
|
||||
ws.write(buf, rdSz);
|
||||
xferSz += rdSz;
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, e.m_name, xferSz);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactorMidFile(xferSz, e.m_fileSz), e.m_name, xferSz);
|
||||
}
|
||||
++m_parent.m_progressIdx;
|
||||
}
|
||||
for (size_t i=0 ; i<fileSz-xferSz ; ++i)
|
||||
ws.write("\xff", 1);
|
||||
|
@ -486,13 +571,13 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||
bool patched;
|
||||
PatchDOL(dolBuf, xferSz, patched);
|
||||
ws.write(dolBuf.get(), xferSz);
|
||||
m_parent.m_progressCB(++m_parent.m_progressIdx, sysName.sys_str() +
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), sysName.sys_str() +
|
||||
(patched ? _S(" [PATCHED]") : _S("")), xferSz);
|
||||
++m_parent.m_progressIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[0x8000];
|
||||
++m_parent.m_progressIdx;
|
||||
while (xferSz < ch.size())
|
||||
{
|
||||
size_t rdSz = rs->read(buf, nod::min(size_t(0x8000), size_t(ch.size() - xferSz)));
|
||||
|
@ -500,8 +585,9 @@ bool DiscBuilderBase::PartitionBuilderBase::recursiveMergeNodes(IPartWriteStream
|
|||
break;
|
||||
ws.write(buf, rdSz);
|
||||
xferSz += rdSz;
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, sysName.sys_str(), xferSz);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactorMidFile(xferSz, ch.size()), sysName.sys_str(), xferSz);
|
||||
}
|
||||
++m_parent.m_progressIdx;
|
||||
}
|
||||
for (size_t i=0 ; i<fileSz-xferSz ; ++i)
|
||||
ws.write("\xff", 1);
|
||||
|
@ -689,9 +775,14 @@ bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream&
|
|||
return false;
|
||||
}
|
||||
|
||||
/* 1st pass - Tally up total progress steps */
|
||||
uint64_t dolInode = GetInode(dolIn);
|
||||
m_parent.m_progressTotal += 2; /* Prep and DOL */
|
||||
recursiveBuildNodesPre(dirIn, dolInode);
|
||||
|
||||
/* Clear file */
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), _S("Preparing output image"), -1);
|
||||
++m_parent.m_progressIdx;
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, _S("Preparing output image"), -1);
|
||||
|
||||
/* Add root node */
|
||||
m_buildNodes.emplace_back(true, m_buildNameOff, 0, 1);
|
||||
|
@ -716,14 +807,14 @@ bool DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(IPartWriteStream&
|
|||
return false;
|
||||
bool patched;
|
||||
size_t xferSz = PatchDOL(*rs, ws, dolStat.st_size, patched);
|
||||
m_parent.m_progressCB(++m_parent.m_progressIdx, SystemString(dolIn) +
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), SystemString(dolIn) +
|
||||
(patched ? _S(" [PATCHED]") : _S("")), xferSz);
|
||||
++m_parent.m_progressIdx;
|
||||
for (size_t i=0 ; i<fileSz-xferSz ; ++i)
|
||||
ws.write("\xff", 1);
|
||||
}
|
||||
|
||||
/* Gather files in root directory */
|
||||
uint64_t dolInode = GetInode(dolIn);
|
||||
if (!recursiveBuildNodes(ws, true, dirIn, dolInode))
|
||||
return false;
|
||||
if (!recursiveBuildNodes(ws, false, dirIn, dolInode))
|
||||
|
@ -759,9 +850,13 @@ bool DiscBuilderBase::PartitionBuilderBase::mergeFromDirectory(IPartWriteStream&
|
|||
return false;
|
||||
}
|
||||
|
||||
/* 1st pass - Tally up total progress steps */
|
||||
m_parent.m_progressTotal += 2; /* Prep and DOL */
|
||||
recursiveMergeNodesPre(&partIn->getFSTRoot(), dirIn);
|
||||
|
||||
/* Clear file */
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), _S("Preparing output image"), -1);
|
||||
++m_parent.m_progressIdx;
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, _S("Preparing output image"), -1);
|
||||
|
||||
/* Add root node */
|
||||
m_buildNodes.emplace_back(true, m_buildNameOff, 0, 1);
|
||||
|
@ -780,8 +875,9 @@ bool DiscBuilderBase::PartitionBuilderBase::mergeFromDirectory(IPartWriteStream&
|
|||
bool patched;
|
||||
PatchDOL(dolBuf, xferSz, patched);
|
||||
ws.write(dolBuf.get(), xferSz);
|
||||
m_parent.m_progressCB(++m_parent.m_progressIdx, SystemString(_S("<boot-dol>")) +
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), SystemString(_S("<boot-dol>")) +
|
||||
(patched ? _S(" [PATCHED]") : _S("")), xferSz);
|
||||
++m_parent.m_progressIdx;
|
||||
for (size_t i=0 ; i<fileSz-xferSz ; ++i)
|
||||
ws.write("\xff", 1);
|
||||
}
|
||||
|
|
|
@ -264,7 +264,6 @@ public:
|
|||
return false;
|
||||
char buf[8192];
|
||||
SystemString apploaderName(apploaderIn);
|
||||
++m_parent.m_progressIdx;
|
||||
while (true)
|
||||
{
|
||||
size_t rdSz = rs->read(buf, 8192);
|
||||
|
@ -278,8 +277,9 @@ public:
|
|||
"apploader flows into user area (one or the other is too big)");
|
||||
return false;
|
||||
}
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, apploaderName, xferSz);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderName, xferSz);
|
||||
}
|
||||
++m_parent.m_progressIdx;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -298,7 +298,6 @@ public:
|
|||
std::unique_ptr<uint8_t[]> apploaderBuf = partIn->getApploaderBuf();
|
||||
size_t apploaderSz = partIn->getApploaderSize();
|
||||
SystemString apploaderName(_S("<apploader>"));
|
||||
++m_parent.m_progressIdx;
|
||||
ws.write(apploaderBuf.get(), apploaderSz);
|
||||
xferSz += apploaderSz;
|
||||
if (0x2440 + xferSz >= m_curUser)
|
||||
|
@ -307,31 +306,32 @@ public:
|
|||
"apploader flows into user area (one or the other is too big)");
|
||||
return false;
|
||||
}
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, apploaderName, xferSz);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderName, xferSz);
|
||||
++m_parent.m_progressIdx;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
bool DiscBuilderGCN::buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn,
|
||||
const SystemChar* apploaderIn)
|
||||
EBuildResult DiscBuilderGCN::buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn,
|
||||
const SystemChar* apploaderIn)
|
||||
{
|
||||
if (!m_fileIO->beginWriteStream())
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
if (!CheckFreeSpace(m_outPath.c_str(), 0x57058000))
|
||||
{
|
||||
LogModule.report(logvisor::Error, _S("not enough free disk space for %s"), m_outPath.c_str());
|
||||
return false;
|
||||
return EBuildResult::DiskFull;
|
||||
}
|
||||
m_progressCB(getProgressFactor(), _S("Preallocating image"), -1);
|
||||
++m_progressIdx;
|
||||
m_progressCB(m_progressIdx, _S("Preallocating image"), -1);
|
||||
auto ws = m_fileIO->beginWriteStream(0x57058000 - 1);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
ws->write("", 1);
|
||||
|
||||
PartitionBuilderGCN& pb = static_cast<PartitionBuilderGCN&>(*m_partitions[0]);
|
||||
return pb.buildFromDirectory(dirIn, dolIn, apploaderIn);
|
||||
return pb.buildFromDirectory(dirIn, dolIn, apploaderIn) ? EBuildResult::Success : EBuildResult::Failed;
|
||||
}
|
||||
|
||||
uint64_t DiscBuilderGCN::CalculateTotalSizeRequired(const SystemChar* dirIn, const SystemChar* dolIn)
|
||||
|
@ -361,24 +361,25 @@ DiscMergerGCN::DiscMergerGCN(const SystemChar* outPath, DiscGCN& sourceDisc, FPr
|
|||
: m_sourceDisc(sourceDisc), m_builder(sourceDisc.makeMergeBuilder(outPath, progressCB))
|
||||
{}
|
||||
|
||||
bool DiscMergerGCN::mergeFromDirectory(const SystemChar* dirIn)
|
||||
EBuildResult DiscMergerGCN::mergeFromDirectory(const SystemChar* dirIn)
|
||||
{
|
||||
if (!m_builder.getFileIO().beginWriteStream())
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
if (!CheckFreeSpace(m_builder.m_outPath.c_str(), 0x57058000))
|
||||
{
|
||||
LogModule.report(logvisor::Error, _S("not enough free disk space for %s"), m_builder.m_outPath.c_str());
|
||||
return false;
|
||||
return EBuildResult::DiskFull;
|
||||
}
|
||||
m_builder.m_progressCB(m_builder.getProgressFactor(), _S("Preallocating image"), -1);
|
||||
++m_builder.m_progressIdx;
|
||||
m_builder.m_progressCB(m_builder.m_progressIdx, _S("Preallocating image"), -1);
|
||||
auto ws = m_builder.m_fileIO->beginWriteStream(0x57058000 - 1);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
ws->write("", 1);
|
||||
|
||||
PartitionBuilderGCN& pb = static_cast<PartitionBuilderGCN&>(*m_builder.m_partitions[0]);
|
||||
return pb.mergeFromDirectory(static_cast<PartitionGCN*>(m_sourceDisc.getDataPartition()), dirIn);
|
||||
return pb.mergeFromDirectory(static_cast<PartitionGCN*>(m_sourceDisc.getDataPartition()), dirIn) ?
|
||||
EBuildResult::Success : EBuildResult::Failed;
|
||||
}
|
||||
|
||||
uint64_t DiscMergerGCN::CalculateTotalSizeRequired(DiscGCN& sourceDisc, const SystemChar* dirIn)
|
||||
|
|
|
@ -928,7 +928,6 @@ public:
|
|||
bool good = false;
|
||||
uint64_t attempts = 0;
|
||||
SystemString bfName(_S("Brute force attempts"));
|
||||
++m_parent.m_progressIdx;
|
||||
for (int w=0 ; w<7 ; ++w)
|
||||
{
|
||||
for (uint64_t i=0 ; i<UINT64_MAX ; ++i)
|
||||
|
@ -943,12 +942,13 @@ public:
|
|||
good = true;
|
||||
break;
|
||||
}
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, bfName, attempts);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), bfName, attempts);
|
||||
}
|
||||
if (good)
|
||||
break;
|
||||
}
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, bfName, attempts);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), bfName, attempts);
|
||||
++m_parent.m_progressIdx;
|
||||
|
||||
ws = m_parent.getFileIO().beginWriteStream(m_baseOffset + 0x2C0);
|
||||
if (!ws)
|
||||
|
@ -994,7 +994,6 @@ public:
|
|||
return false;
|
||||
char buf[8192];
|
||||
SystemString apploaderName(apploaderIn);
|
||||
++m_parent.m_progressIdx;
|
||||
while (true)
|
||||
{
|
||||
size_t rdSz = rs->read(buf, 8192);
|
||||
|
@ -1008,8 +1007,9 @@ public:
|
|||
"apploader flows into user area (one or the other is too big)");
|
||||
return false;
|
||||
}
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, apploaderName, xferSz);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderName, xferSz);
|
||||
}
|
||||
++m_parent.m_progressIdx;
|
||||
return true;
|
||||
}, phBuf.get(), phSz, theStat.st_size);
|
||||
}
|
||||
|
@ -1030,7 +1030,6 @@ public:
|
|||
std::unique_ptr<uint8_t[]> apploaderBuf = partIn->getApploaderBuf();
|
||||
size_t apploaderSz = partIn->getApploaderSize();
|
||||
SystemString apploaderName(_S("<apploader>"));
|
||||
++m_parent.m_progressIdx;
|
||||
cws.write(apploaderBuf.get(), apploaderSz);
|
||||
xferSz += apploaderSz;
|
||||
if (0x2440 + xferSz >= 0x1F0000)
|
||||
|
@ -1039,69 +1038,70 @@ public:
|
|||
"apploader flows into user area (one or the other is too big)");
|
||||
return false;
|
||||
}
|
||||
m_parent.m_progressCB(m_parent.m_progressIdx, apploaderName, xferSz);
|
||||
m_parent.m_progressCB(m_parent.getProgressFactor(), apploaderName, xferSz);
|
||||
++m_parent.m_progressIdx;
|
||||
return true;
|
||||
}, phBuf.get(), phSz, partIn->getApploaderSize());
|
||||
}
|
||||
};
|
||||
|
||||
bool DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn,
|
||||
const SystemChar* apploaderIn, const SystemChar* partHeadIn)
|
||||
EBuildResult DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn,
|
||||
const SystemChar* apploaderIn, const SystemChar* partHeadIn)
|
||||
{
|
||||
PartitionBuilderWii& pb = static_cast<PartitionBuilderWii&>(*m_partitions[0]);
|
||||
uint64_t filledSz = pb.m_baseOffset;
|
||||
if (!m_fileIO->beginWriteStream())
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
|
||||
if (!CheckFreeSpace(m_outPath.c_str(), m_discCapacity))
|
||||
{
|
||||
LogModule.report(logvisor::Error, _S("not enough free disk space for %s"), m_outPath.c_str());
|
||||
return false;
|
||||
return EBuildResult::DiskFull;
|
||||
}
|
||||
m_progressCB(getProgressFactor(), _S("Preallocating image"), -1);
|
||||
++m_progressIdx;
|
||||
m_progressCB(m_progressIdx, _S("Preallocating image"), -1);
|
||||
std::unique_ptr<IFileIO::IWriteStream> ws = m_fileIO->beginWriteStream(m_discCapacity - 1);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
ws->write("", 1);
|
||||
|
||||
/* Assemble image */
|
||||
filledSz = pb.buildFromDirectory(dirIn, dolIn, apploaderIn, partHeadIn);
|
||||
if (filledSz == -1)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
else if (filledSz >= uint64_t(m_discCapacity))
|
||||
{
|
||||
LogModule.report(logvisor::Error, "data partition exceeds disc capacity");
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
}
|
||||
|
||||
m_progressCB(getProgressFactor(), _S("Finishing Disc"), -1);
|
||||
++m_progressIdx;
|
||||
m_progressCB(m_progressIdx, _S("Finishing Disc"), -1);
|
||||
|
||||
/* Populate disc header */
|
||||
ws = m_fileIO->beginWriteStream(0);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
Header header(pb.getGameID(), pb.getGameTitle().c_str(), true, 0, 0, 0);
|
||||
header.write(*ws);
|
||||
|
||||
/* Populate partition info */
|
||||
ws = m_fileIO->beginWriteStream(0x40000);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
uint32_t vals[2] = {SBig(uint32_t(1)), SBig(uint32_t(0x40020 >> uint64_t(2)))};
|
||||
ws->write(vals, 8);
|
||||
|
||||
ws = m_fileIO->beginWriteStream(0x40020);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
vals[0] = SBig(uint32_t(pb.m_baseOffset >> uint64_t(2)));
|
||||
ws->write(vals, 4);
|
||||
|
||||
/* Populate region info */
|
||||
ws = m_fileIO->beginWriteStream(0x4E000);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
const char* gameID = pb.getGameID();
|
||||
if (gameID[3] == 'P')
|
||||
vals[0] = SBig(uint32_t(2));
|
||||
|
@ -1114,14 +1114,14 @@ bool DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn, const SystemCha
|
|||
/* Make disc unrated */
|
||||
ws = m_fileIO->beginWriteStream(0x4E010);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
for (int i=0 ; i<16 ; ++i)
|
||||
ws->write("\x80", 1);
|
||||
|
||||
/* Fill image to end */
|
||||
ws = m_fileIO->beginWriteStream(filledSz);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
uint8_t fillBuf[512];
|
||||
memset(fillBuf, 0xff, 512);
|
||||
for (size_t i=m_discCapacity-filledSz ; i>0 ;)
|
||||
|
@ -1136,7 +1136,7 @@ bool DiscBuilderWii::buildFromDirectory(const SystemChar* dirIn, const SystemCha
|
|||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return EBuildResult::Success;
|
||||
}
|
||||
|
||||
uint64_t DiscBuilderWii::CalculateTotalSizeRequired(const SystemChar* dirIn, const SystemChar* dolIn,
|
||||
|
@ -1172,61 +1172,61 @@ DiscMergerWii::DiscMergerWii(const SystemChar* outPath, DiscWii& sourceDisc,
|
|||
: m_sourceDisc(sourceDisc), m_builder(sourceDisc.makeMergeBuilder(outPath, dualLayer, progressCB))
|
||||
{}
|
||||
|
||||
bool DiscMergerWii::mergeFromDirectory(const SystemChar* dirIn)
|
||||
EBuildResult DiscMergerWii::mergeFromDirectory(const SystemChar* dirIn)
|
||||
{
|
||||
PartitionBuilderWii& pb = static_cast<PartitionBuilderWii&>(*m_builder.m_partitions[0]);
|
||||
uint64_t filledSz = pb.m_baseOffset;
|
||||
if (!m_builder.m_fileIO->beginWriteStream())
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
|
||||
if (!CheckFreeSpace(m_builder.m_outPath.c_str(), m_builder.m_discCapacity))
|
||||
{
|
||||
LogModule.report(logvisor::Error, _S("not enough free disk space for %s"), m_builder.m_outPath.c_str());
|
||||
return false;
|
||||
return EBuildResult::DiskFull;
|
||||
}
|
||||
m_builder.m_progressCB(m_builder.getProgressFactor(), _S("Preallocating image"), -1);
|
||||
++m_builder.m_progressIdx;
|
||||
m_builder.m_progressCB(m_builder.m_progressIdx, _S("Preallocating image"), -1);
|
||||
std::unique_ptr<IFileIO::IWriteStream> ws = m_builder.m_fileIO->beginWriteStream(m_builder.m_discCapacity - 1);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
ws->write("", 1);
|
||||
|
||||
/* Assemble image */
|
||||
filledSz = pb.mergeFromDirectory(static_cast<PartitionWii*>(m_sourceDisc.getDataPartition()), dirIn);
|
||||
if (filledSz == -1)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
else if (filledSz >= uint64_t(m_builder.m_discCapacity))
|
||||
{
|
||||
LogModule.report(logvisor::Error, "data partition exceeds disc capacity");
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
}
|
||||
|
||||
m_builder.m_progressCB(m_builder.getProgressFactor(), _S("Finishing Disc"), -1);
|
||||
++m_builder.m_progressIdx;
|
||||
m_builder.m_progressCB(m_builder.m_progressIdx, _S("Finishing Disc"), -1);
|
||||
|
||||
/* Populate disc header */
|
||||
ws = m_builder.m_fileIO->beginWriteStream(0);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
m_sourceDisc.getHeader().write(*ws);
|
||||
|
||||
/* Populate partition info */
|
||||
ws = m_builder.m_fileIO->beginWriteStream(0x40000);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
uint32_t vals[2] = {SBig(uint32_t(1)), SBig(uint32_t(0x40020 >> uint64_t(2)))};
|
||||
ws->write(vals, 8);
|
||||
|
||||
ws = m_builder.m_fileIO->beginWriteStream(0x40020);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
vals[0] = SBig(uint32_t(pb.m_baseOffset >> uint64_t(2)));
|
||||
ws->write(vals, 4);
|
||||
|
||||
/* Populate region info */
|
||||
ws = m_builder.m_fileIO->beginWriteStream(0x4E000);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
const char* gameID = pb.getGameID();
|
||||
if (gameID[3] == 'P')
|
||||
vals[0] = SBig(uint32_t(2));
|
||||
|
@ -1239,14 +1239,14 @@ bool DiscMergerWii::mergeFromDirectory(const SystemChar* dirIn)
|
|||
/* Make disc unrated */
|
||||
ws = m_builder.m_fileIO->beginWriteStream(0x4E010);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
for (int i=0 ; i<16 ; ++i)
|
||||
ws->write("\x80", 1);
|
||||
|
||||
/* Fill image to end */
|
||||
ws = m_builder.m_fileIO->beginWriteStream(filledSz);
|
||||
if (!ws)
|
||||
return false;
|
||||
return EBuildResult::Failed;
|
||||
uint8_t fillBuf[512];
|
||||
memset(fillBuf, 0xff, 512);
|
||||
for (size_t i=m_builder.m_discCapacity-filledSz ; i>0 ;)
|
||||
|
@ -1261,7 +1261,7 @@ bool DiscMergerWii::mergeFromDirectory(const SystemChar* dirIn)
|
|||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return EBuildResult::Success;
|
||||
}
|
||||
|
||||
uint64_t DiscMergerWii::CalculateTotalSizeRequired(DiscWii& sourceDisc,
|
||||
|
|
|
@ -83,29 +83,6 @@ public:
|
|||
}
|
||||
return fwrite(buf, 1, length, fp);
|
||||
}
|
||||
uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length)
|
||||
{
|
||||
uint64_t read = 0;
|
||||
uint8_t buf[0x7c00];
|
||||
while (length)
|
||||
{
|
||||
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
||||
uint64_t readSz = discio.read(buf, thisSz);
|
||||
if (thisSz != readSz)
|
||||
{
|
||||
LogModule.report(logvisor::Error, "unable to read enough from disc");
|
||||
return read;
|
||||
}
|
||||
if (write(buf, readSz) != readSz)
|
||||
{
|
||||
LogModule.report(logvisor::Error, "unable to write in file");
|
||||
return read;
|
||||
}
|
||||
length -= thisSz;
|
||||
read += thisSz;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
};
|
||||
std::unique_ptr<IWriteStream> beginWriteStream() const
|
||||
{
|
||||
|
|
|
@ -95,29 +95,6 @@ public:
|
|||
WriteFile(fp, buf, length, &ret, nullptr);
|
||||
return ret;
|
||||
}
|
||||
uint64_t copyFromDisc(IPartReadStream& discio, uint64_t length)
|
||||
{
|
||||
uint64_t read = 0;
|
||||
uint8_t buf[0x7c00];
|
||||
while (length)
|
||||
{
|
||||
uint64_t thisSz = nod::min(uint64_t(0x7c00), length);
|
||||
uint64_t readSz = discio.read(buf, thisSz);
|
||||
if (thisSz != readSz)
|
||||
{
|
||||
LogModule.report(logvisor::Error, "unable to read enough from disc");
|
||||
return read;
|
||||
}
|
||||
if (write(buf, readSz) != readSz)
|
||||
{
|
||||
LogModule.report(logvisor::Error, "unable to write in file");
|
||||
return read;
|
||||
}
|
||||
length -= thisSz;
|
||||
read += thisSz;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
};
|
||||
std::unique_ptr<IWriteStream> beginWriteStream() const
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue