mirror of
https://github.com/AxioDL/nod.git
synced 2025-12-16 08:27:19 +00:00
Single-pass image creation refactor
This commit is contained in:
@@ -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;}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
Reference in New Issue
Block a user