Single-pass image creation refactor

This commit is contained in:
Jack Andersen
2016-01-24 16:00:02 -10:00
parent 5d5dfdc3da
commit c4aaecbc8f
7 changed files with 427 additions and 282 deletions

View File

@@ -76,7 +76,8 @@ struct Header
m_gcnMagic = 0xC2339F3D;
}
void write(IFileIO::IWriteStream& ws) const
template <class WriteStream>
void write(WriteStream& ws) const
{
Header hs(*this);
hs.m_wiiMagic = SBig(hs.m_wiiMagic);
@@ -316,9 +317,9 @@ public:
std::vector<FSTNode> m_buildNodes;
std::vector<std::string> m_buildNames;
size_t m_buildNameOff = 0;
virtual uint64_t userAllocate(uint64_t reqSz)=0;
virtual uint64_t userAllocate(uint64_t reqSz, IPartWriteStream& ws)=0;
virtual uint32_t packOffset(uint64_t offset) const=0;
void recursiveBuildNodes(bool system, const SystemChar* dirIn, uint64_t dolInode);
void recursiveBuildNodes(IPartWriteStream& ws, bool system, const SystemChar* dirIn, uint64_t dolInode);
void recursiveBuildFST(const SystemChar* dirIn, uint64_t dolInode,
std::function<void(void)> incParents);
void addBuildName(const SystemString& str)
@@ -342,22 +343,25 @@ public:
{
memcpy(m_gameID, gameID, 6);
}
bool buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn,
virtual std::unique_ptr<IPartWriteStream> beginWriteStream(uint64_t offset)=0;
bool buildFromDirectory(IPartWriteStream& ws,
const SystemChar* dirIn, const SystemChar* dolIn,
const SystemChar* apploaderIn);
const char* getGameID() const {return m_gameID;}
const std::string& getGameTitle() const {return m_gameTitle;}
};
protected:
const SystemChar* m_outPath;
std::unique_ptr<IFileIO> m_fileIO;
std::vector<std::unique_ptr<PartitionBuilderBase>> m_partitions;
public:
std::function<void(size_t idx, const SystemString&, size_t)> m_progressCB;
size_t m_progressIdx = 0;
virtual ~DiscBuilderBase() {}
DiscBuilderBase(std::unique_ptr<IFileIO>&& fio,
DiscBuilderBase(const SystemChar* outPath,
std::function<void(size_t idx, const SystemString&, size_t)> progressCB)
: m_fileIO(std::move(fio)), m_progressCB(progressCB) {}
: m_fileIO(std::move(NewFileIO(outPath))), m_outPath(outPath), m_progressCB(progressCB) {}
IFileIO& getFileIO() {return *m_fileIO;}
};

View File

@@ -15,13 +15,14 @@ public:
class DiscBuilderWii : public DiscBuilderBase
{
const SystemChar* m_outPath;
bool m_dualLayer;
public:
DiscBuilderWii(const SystemChar* outPath, const char gameID[6], const char* gameTitle, bool dualLayer,
std::function<void(size_t, const SystemString&, size_t)> progressCB);
bool buildFromDirectory(const SystemChar* dirIn, const SystemChar* dolIn,
const SystemChar* apploaderIn, const SystemChar* partHeadIn);
bool buildFromDirectory(const SystemChar* dirIn,
const SystemChar* dolIn,
const SystemChar* apploaderIn,
const SystemChar* partHeadIn);
};
}

View File

@@ -47,9 +47,9 @@ struct IPartReadStream
struct IPartWriteStream
{
virtual ~IPartWriteStream() {}
virtual void seek(int64_t offset, int whence=SEEK_SET)=0;
virtual void close()=0;
virtual uint64_t position() const=0;
virtual uint64_t write(void* buf, uint64_t length)=0;
virtual uint64_t write(const void* buf, uint64_t length)=0;
};
#if NOD_ATHENA
@@ -72,24 +72,6 @@ public:
inline atUint64 readUBytesToBuf(void* buf, atUint64 sz) {m_rs->read(buf, sz); return sz;}
};
class AthenaPartWriteStream : public Athena::io::IStreamWriter
{
std::unique_ptr<IPartWriteStream> m_ws;
public:
AthenaPartWriteStream(std::unique_ptr<IPartWriteStream>&& ws) : m_ws(std::move(ws)) {}
inline void seek(atInt64 off, Athena::SeekOrigin origin)
{
if (origin == Athena::Begin)
m_ws->seek(off, SEEK_SET);
else if (origin == Athena::Current)
m_ws->seek(off, SEEK_CUR);
}
inline atUint64 position() const {return m_ws->position();}
inline atUint64 length() const {return 0;}
inline void writeUBytes(const atUint8* buf, atUint64 len) {m_ws->write((void*)buf, len);}
};
#endif
}

View File

@@ -16,6 +16,9 @@
#include <sys/file.h>
#include <unistd.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/statvfs.h>
#endif
#include <sys/stat.h>
@@ -261,6 +264,21 @@ static inline int FSeek(FILE* fp, int64_t offset, int whence)
#endif
}
static inline bool CheckFreeSpace(const SystemChar* path, size_t reqSz)
{
#if _WIN32
ULARGE_INTEGER freeBytes;
if (!GetDiskFreeSpaceExW(path, &freeBytes, nullptr, nullptr))
LogModule.report(LogVisor::FatalError, "GetDiskFreeSpaceExW %s: %d", path, GetLastError());
return reqSz < freeBytes;
#else
struct statvfs svfs;
if (statvfs(path, &svfs))
LogModule.report(LogVisor::FatalError, "statvfs %s: %s", path, strerror(errno));
return reqSz < svfs.f_bsize * svfs.f_bfree;
#endif
}
}
#endif // __NOD_UTIL_HPP__