nod/include/DiscBase.hpp

130 lines
3.2 KiB
C++
Raw Normal View History

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__