2015-06-26 19:30:03 +00:00
|
|
|
#ifndef __NOD_DISC_BASE__
|
|
|
|
#define __NOD_DISC_BASE__
|
|
|
|
|
2015-06-28 05:43:53 +00:00
|
|
|
#include <vector>
|
2015-06-26 19:30:03 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
2015-06-28 05:43:53 +00:00
|
|
|
#include "Util.hpp"
|
2015-06-26 19:30:03 +00:00
|
|
|
#include "IDiscIO.hpp"
|
|
|
|
#include "IFileIO.hpp"
|
|
|
|
|
|
|
|
namespace NOD
|
|
|
|
{
|
|
|
|
|
|
|
|
class DiscBase
|
|
|
|
{
|
2015-06-26 20:01:15 +00:00
|
|
|
public:
|
2015-06-28 05:43:53 +00:00
|
|
|
struct Header
|
|
|
|
{
|
|
|
|
char gameID[6];
|
|
|
|
char discNum;
|
|
|
|
char discVersion;
|
|
|
|
char audioStreaming;
|
|
|
|
char streamBufSz;
|
|
|
|
char unk[14];
|
|
|
|
uint32_t wiiMagic;
|
|
|
|
uint32_t gcnMagic;
|
|
|
|
char gameTitle[64];
|
|
|
|
|
|
|
|
Header(IDiscIO& dio)
|
|
|
|
{
|
|
|
|
std::unique_ptr<IDiscIO::IReadStream> s = dio.beginReadStream(0);
|
|
|
|
s->read(this, sizeof(*this));
|
|
|
|
wiiMagic = SBig(wiiMagic);
|
|
|
|
gcnMagic = SBig(gcnMagic);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FSTNode
|
|
|
|
{
|
|
|
|
uint32_t typeAndNameOff;
|
|
|
|
uint32_t offset;
|
|
|
|
uint32_t length;
|
|
|
|
FSTNode(IDiscIO::IReadStream& s)
|
|
|
|
{
|
|
|
|
s.read(this, 12);
|
|
|
|
typeAndNameOff = SBig(typeAndNameOff);
|
|
|
|
offset = SBig(offset);
|
|
|
|
length = SBig(length);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct IPartReadStream
|
2015-06-26 20:01:15 +00:00
|
|
|
{
|
|
|
|
virtual size_t read(void* buf, size_t length)=0;
|
|
|
|
};
|
|
|
|
|
2015-06-28 05:43:53 +00:00
|
|
|
struct IPartWriteStream
|
2015-06-26 20:01:15 +00:00
|
|
|
{
|
|
|
|
virtual size_t write(void* buf, size_t length)=0;
|
|
|
|
};
|
|
|
|
|
2015-06-28 05:43:53 +00:00
|
|
|
class IPartition
|
2015-06-26 19:30:03 +00:00
|
|
|
{
|
2015-06-26 20:01:15 +00:00
|
|
|
public:
|
2015-06-26 19:30:03 +00:00
|
|
|
enum Kind
|
|
|
|
{
|
|
|
|
PART_DATA,
|
2015-06-28 05:43:53 +00:00
|
|
|
PART_UPDATE,
|
|
|
|
PART_CHANNEL
|
2015-06-26 19:30:03 +00:00
|
|
|
};
|
2015-06-28 05:43:53 +00:00
|
|
|
class Node
|
2015-06-26 19:30:03 +00:00
|
|
|
{
|
2015-06-28 05:43:53 +00:00
|
|
|
public:
|
|
|
|
enum Kind
|
|
|
|
{
|
|
|
|
NODE_FILE,
|
|
|
|
NODE_DIRECTORY
|
|
|
|
};
|
|
|
|
private:
|
|
|
|
const IPartition& m_parent;
|
|
|
|
Kind m_kind;
|
|
|
|
std::string m_name;
|
|
|
|
|
2015-06-26 19:30:03 +00:00
|
|
|
std::unique_ptr<IFileIO> m_hddFile;
|
|
|
|
size_t m_discOffset;
|
|
|
|
size_t m_discLength;
|
2015-06-28 05:43:53 +00:00
|
|
|
|
2015-06-26 20:01:15 +00:00
|
|
|
public:
|
2015-06-28 05:43:53 +00:00
|
|
|
Node(const IPartition& parent, bool isDir, const char* name)
|
|
|
|
: m_parent(parent), m_kind(isDir ? NODE_DIRECTORY : NODE_FILE), m_name(name) {}
|
|
|
|
inline Kind getKind() const {return m_kind;}
|
2015-06-29 05:35:25 +00:00
|
|
|
std::unique_ptr<IPartReadStream> beginReadStream() const
|
|
|
|
{
|
|
|
|
if (m_kind != NODE_FILE)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("unable to stream a non-file");
|
|
|
|
return std::unique_ptr<IPartReadStream>();
|
|
|
|
}
|
|
|
|
return m_parent.beginReadStream(m_discOffset);
|
|
|
|
}
|
2015-06-26 19:30:03 +00:00
|
|
|
};
|
2015-06-28 05:43:53 +00:00
|
|
|
protected:
|
2015-06-29 05:35:25 +00:00
|
|
|
std::vector<Node> m_files;
|
|
|
|
void parseFST();
|
|
|
|
|
2015-06-28 05:43:53 +00:00
|
|
|
const DiscBase& m_parent;
|
2015-06-26 19:30:03 +00:00
|
|
|
Kind m_kind;
|
2015-06-28 05:43:53 +00:00
|
|
|
size_t m_offset;
|
2015-06-26 20:01:15 +00:00
|
|
|
public:
|
2015-06-28 05:43:53 +00:00
|
|
|
IPartition(const DiscBase& parent, Kind kind, size_t offset)
|
|
|
|
: m_parent(parent), m_kind(kind), m_offset(offset) {}
|
|
|
|
inline Kind getKind() const {return m_kind;}
|
2015-06-29 05:35:25 +00:00
|
|
|
virtual std::unique_ptr<IPartReadStream> beginReadStream(size_t offset=0) const=0;
|
2015-06-26 19:30:03 +00:00
|
|
|
};
|
|
|
|
|
2015-06-28 05:43:53 +00:00
|
|
|
protected:
|
|
|
|
std::unique_ptr<IDiscIO> m_discIO;
|
|
|
|
Header m_header;
|
|
|
|
std::vector<std::unique_ptr<IPartition>> m_partitions;
|
|
|
|
public:
|
|
|
|
DiscBase(std::unique_ptr<IDiscIO>&& dio);
|
|
|
|
virtual bool commit()=0;
|
|
|
|
inline Header getHeader() const {return m_header;}
|
|
|
|
inline const IDiscIO& getDiscIO() const {return *m_discIO.get();}
|
2015-06-26 19:30:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // __NOD_DISC_BASE__
|