WIP context

This commit is contained in:
Phillip Stephens 2015-09-27 18:55:59 -07:00
parent 8cd695c229
commit f4c606c4eb
4 changed files with 42 additions and 14 deletions

View File

@ -29,13 +29,19 @@ int main(int argc, char* argv[])
/* Enable logging to console */ /* Enable logging to console */
LogVisor::RegisterConsoleLogger(); LogVisor::RegisterConsoleLogger();
NOD::ExtractionContext ctx = { true, true, [&](const std::string& str){
fprintf(stderr, "%s\n", str.c_str());
}};
const NOD::SystemChar* inDir = nullptr; const NOD::SystemChar* inDir = nullptr;
const NOD::SystemChar* outDir = _S("."); const NOD::SystemChar* outDir = _S(".");
bool force = false;
for (int a=2 ; a<argc ; ++a) for (int a=2 ; a<argc ; ++a)
{ {
if (argv[a][0] == '-' && argv[a][1] == 'f') if (argv[a][0] == '-' && argv[a][1] == 'f')
force = true; ctx.force = true;
else if (argv[a][0] == '-' && argv[a][1] == 'v')
ctx.verbose = true;
else if (!inDir) else if (!inDir)
inDir = argv[a]; inDir = argv[a];
else else
@ -52,7 +58,7 @@ int main(int argc, char* argv[])
if (!dataPart) if (!dataPart)
return -1; return -1;
if (!dataPart->extractToDirectory(outDir, force)) if (!dataPart->extractToDirectory(outDir, ctx))
return -1; return -1;
} }
else if (!strcasecmp(argv[1], _S("make"))) else if (!strcasecmp(argv[1], _S("make")))

View File

@ -13,6 +13,7 @@
namespace NOD namespace NOD
{ {
class ExtractionContext;
class DiscBase class DiscBase
{ {
public: public:
@ -163,7 +164,7 @@ public:
return end(); return end();
} }
bool extractToDirectory(const SystemString& basePath, bool force=false) const; bool extractToDirectory(const SystemString& basePath, const ExtractionContext& ctx) const;
}; };
protected: protected:
uint64_t m_dolOff; uint64_t m_dolOff;
@ -193,7 +194,7 @@ public:
{return beginReadStream(0x2440 + offset);} {return beginReadStream(0x2440 + offset);}
inline const Node& getFSTRoot() const {return m_nodes[0];} inline const Node& getFSTRoot() const {return m_nodes[0];}
inline Node& getFSTRoot() {return m_nodes[0];} inline Node& getFSTRoot() {return m_nodes[0];}
bool extractToDirectory(const SystemString& path, bool force=false); bool extractToDirectory(const SystemString& path, const ExtractionContext& ctx);
inline uint64_t getDOLSize() const {return m_dolSz;} inline uint64_t getDOLSize() const {return m_dolSz;}
inline std::unique_ptr<uint8_t[]> getDOLBuf() const inline std::unique_ptr<uint8_t[]> getDOLBuf() const
@ -245,10 +246,10 @@ public:
return part.get(); return part.get();
return nullptr; return nullptr;
} }
inline void extractToDirectory(const SystemString& path, bool force=false) inline void extractToDirectory(const SystemString& path, const ExtractionContext& ctx)
{ {
for (std::unique_ptr<IPartition>& part : m_partitions) for (std::unique_ptr<IPartition>& part : m_partitions)
part->extractToDirectory(path, force); part->extractToDirectory(path, ctx);
} }
}; };

View File

@ -2,6 +2,7 @@
#define __NOD_LIB__ #define __NOD_LIB__
#include <memory> #include <memory>
#include <functional>
#include <LogVisor/LogVisor.hpp> #include <LogVisor/LogVisor.hpp>
#include "Util.hpp" #include "Util.hpp"
@ -10,6 +11,13 @@ namespace NOD
class DiscBase; class DiscBase;
struct ExtractionContext final
{
bool verbose : 1;
bool force : 1;
std::function<void(const std::string&)> progressCB;
};
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path); std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path);
std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii); std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii);

View File

@ -1,5 +1,6 @@
#include "NOD/DiscBase.hpp" #include "NOD/DiscBase.hpp"
#include "NOD/IFileIO.hpp" #include "NOD/IFileIO.hpp"
#include "NOD/NOD.hpp"
#include <errno.h> #include <errno.h>
#ifndef _WIN32 #ifndef _WIN32
@ -60,25 +61,33 @@ void DiscBase::IPartition::parseDOL(IPartReadStream& s)
m_dolSz = dolSize; m_dolSz = dolSize;
} }
bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath, bool force) const bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath, const ExtractionContext& ctx) const
{ {
SystemStringView nameView(getName()); SystemStringView nameView(getName());
SystemString path = basePath + _S("/") + nameView.sys_str(); SystemString path = basePath + _S("/") + nameView.sys_str();
if (m_kind == NODE_DIRECTORY) if (m_kind == NODE_DIRECTORY)
{ {
if (ctx.verbose && ctx.progressCB && !getName().empty())
ctx.progressCB(getName());
if (Mkdir(path.c_str(), 0755) && errno != EEXIST) if (Mkdir(path.c_str(), 0755) && errno != EEXIST)
{ {
LogModule.report(LogVisor::Error, _S("unable to mkdir '%s'"), path.c_str()); LogModule.report(LogVisor::Error, _S("unable to mkdir '%s'"), path.c_str());
return false; return false;
} }
for (Node& subnode : *this) for (Node& subnode : *this)
if (!subnode.extractToDirectory(path, force)) if (!subnode.extractToDirectory(path, ctx))
return false; return false;
if (ctx.verbose && ctx.progressCB)
ctx.progressCB(getName());
} }
else if (m_kind == NODE_FILE) else if (m_kind == NODE_FILE)
{ {
Sstat theStat; Sstat theStat;
if (force || Stat(path.c_str(), &theStat)) if (ctx.verbose && ctx.progressCB)
ctx.progressCB(getName());
if (ctx.force || Stat(path.c_str(), &theStat))
{ {
std::unique_ptr<IPartReadStream> rs = beginReadStream(); std::unique_ptr<IPartReadStream> rs = beginReadStream();
std::unique_ptr<IFileIO::IWriteStream> ws = NewFileIO(path)->beginWriteStream(); std::unique_ptr<IFileIO::IWriteStream> ws = NewFileIO(path)->beginWriteStream();
@ -88,7 +97,7 @@ bool DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath
return true; return true;
} }
bool DiscBase::IPartition::extractToDirectory(const SystemString& path, bool force) bool DiscBase::IPartition::extractToDirectory(const SystemString& path, const ExtractionContext& ctx)
{ {
Sstat theStat; Sstat theStat;
if (Mkdir(path.c_str(), 0755) && errno != EEXIST) if (Mkdir(path.c_str(), 0755) && errno != EEXIST)
@ -99,22 +108,26 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path, bool for
/* Extract Apploader */ /* Extract Apploader */
SystemString apploaderPath = path + _S("/apploader.bin"); SystemString apploaderPath = path + _S("/apploader.bin");
if (force || Stat(apploaderPath.c_str(), &theStat)) if (ctx.force || Stat(apploaderPath.c_str(), &theStat))
{ {
if (ctx.verbose && ctx.progressCB)
ctx.progressCB("apploader.bin");
std::unique_ptr<uint8_t[]> buf = getApploaderBuf(); std::unique_ptr<uint8_t[]> buf = getApploaderBuf();
NewFileIO(apploaderPath)->beginWriteStream()->write(buf.get(), m_apploaderSz); NewFileIO(apploaderPath)->beginWriteStream()->write(buf.get(), m_apploaderSz);
} }
/* Extract Dol */ /* Extract Dol */
SystemString dolPath = path + _S("/main.dol"); SystemString dolPath = path + _S("/main.dol");
if (force || Stat(dolPath.c_str(), &theStat)) if (ctx.force || Stat(dolPath.c_str(), &theStat))
{ {
if (ctx.verbose && ctx.progressCB)
ctx.progressCB("main.dol");
std::unique_ptr<uint8_t[]> buf = getDOLBuf(); std::unique_ptr<uint8_t[]> buf = getDOLBuf();
NewFileIO(dolPath)->beginWriteStream()->write(buf.get(), m_dolSz); NewFileIO(dolPath)->beginWriteStream()->write(buf.get(), m_dolSz);
} }
/* Extract Filesystem */ /* Extract Filesystem */
return m_nodes[0].extractToDirectory(path, force); return m_nodes[0].extractToDirectory(path, ctx);
} }
} }