isolated includes with NOD directory

This commit is contained in:
Jack Andersen 2015-07-02 08:33:55 -10:00
parent a1b2a262bf
commit 5c736af2b0
21 changed files with 217 additions and 90 deletions

View File

@ -7,12 +7,12 @@ SUBDIRS += lib driver
driver.depends += lib driver.depends += lib
HEADERS += \ HEADERS += \
include/Util.hpp \ include/NOD/Util.hpp \
include/NODLib.hpp \ include/NOD/NOD.hpp \
include/IDiscIO.hpp \ include/NOD/IDiscIO.hpp \
include/IFileIO.hpp \ include/NOD/IFileIO.hpp \
include/DiscBase.hpp \ include/NOD/DiscBase.hpp \
include/DiscGCN.hpp \ include/NOD/DiscGCN.hpp \
include/DiscWii.hpp \ include/NOD/DiscWii.hpp \
include/aes.hpp include/NOD/aes.hpp

View File

@ -1,6 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "NODLib.hpp" #include "NOD/NOD.hpp"
static void printHelp() static void printHelp()
{ {

View File

@ -121,7 +121,7 @@ public:
inline DirectoryIterator begin() const {return DirectoryIterator(m_childrenBegin);} inline DirectoryIterator begin() const {return DirectoryIterator(m_childrenBegin);}
inline DirectoryIterator end() const {return DirectoryIterator(m_childrenEnd);} inline DirectoryIterator end() const {return DirectoryIterator(m_childrenEnd);}
void extractToDirectory(const std::string& basePath, bool force=false); void extractToDirectory(const SystemString& basePath, bool force=false);
}; };
protected: protected:
uint64_t m_dolOff; uint64_t m_dolOff;
@ -142,13 +142,7 @@ public:
virtual std::unique_ptr<IPartReadStream> beginReadStream(uint64_t offset=0) const=0; virtual std::unique_ptr<IPartReadStream> beginReadStream(uint64_t offset=0) const=0;
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];}
std::string pathOfNode(const Node& node); void extractToDirectory(const SystemString& path, bool force=false);
void extractToDirectory(const std::string& path, bool force=false);
private:
bool _recursivePathOfNode(const std::string& basePath,
const Node& refNode,
const Node& curNode,
std::string& result);
}; };
protected: protected:
@ -174,7 +168,7 @@ public:
return part.get(); return part.get();
return nullptr; return nullptr;
} }
inline void extractToDirectory(const std::string& path, bool force=false) inline void extractToDirectory(const SystemString& path, bool force=false)
{ {
for (std::unique_ptr<IPartition>& part : m_partitions) for (std::unique_ptr<IPartition>& part : m_partitions)
part->extractToDirectory(path, force); part->extractToDirectory(path, force);

View File

@ -4,6 +4,7 @@
#include <memory> #include <memory>
#include <stdlib.h> #include <stdlib.h>
#include "IDiscIO.hpp" #include "IDiscIO.hpp"
#include "Util.hpp"
namespace NOD namespace NOD
{ {
@ -31,7 +32,7 @@ public:
virtual std::unique_ptr<IReadStream> beginReadStream() const=0; virtual std::unique_ptr<IReadStream> beginReadStream() const=0;
}; };
std::unique_ptr<IFileIO> NewFileIO(const std::string& path); std::unique_ptr<IFileIO> NewFileIO(const SystemString& path);
std::unique_ptr<IFileIO> NewMemIO(void* buf, uint64_t size); std::unique_ptr<IFileIO> NewMemIO(void* buf, uint64_t size);
} }

View File

@ -2,20 +2,20 @@
#define __NOD_LIB__ #define __NOD_LIB__
#include <memory> #include <memory>
#include "Util.hpp"
namespace NOD namespace NOD
{ {
class DiscBase; class DiscBase;
std::unique_ptr<DiscBase> OpenDiscFromImage(const char* path); std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path);
std::unique_ptr<DiscBase> OpenDiscFromImage(const char* path, bool& isWii); std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii);
} }
#include "DiscGCN.hpp" #include "DiscGCN.hpp"
#include "DiscWii.hpp" #include "DiscWii.hpp"
#include "IDiscIO.hpp" #include "IDiscIO.hpp"
#include "Util.hpp"
#endif // __NOD_LIB__ #endif // __NOD_LIB__

View File

@ -1,9 +1,78 @@
#ifndef __NOD_UTIL_HPP__ #ifndef __NOD_UTIL_HPP__
#define __NOD_UTIL_HPP__ #define __NOD_UTIL_HPP__
#include <string>
#include <algorithm>
namespace NOD namespace NOD
{ {
/* System char type */
#if _WIN32 && UNICODE
#include <wctype.h>
#define NOD_UCS2 1
#include <ctype.h>
#endif
/* String Converters */
std::string WideToUTF8(const std::wstring& src);
std::wstring UTF8ToWide(const std::string& src);
/* String-converting views */
#if NOD_UCS2
typedef wchar_t SystemChar;
typedef std::wstring SystemString;
static inline void ToLower(SystemString& str)
{std::transform(str.begin(), str.end(), str.begin(), towlower);}
static inline void ToUpper(SystemString& str)
{std::transform(str.begin(), str.end(), str.begin(), towupper);}
class SystemUTF8View
{
std::string m_utf8;
public:
SystemUTF8View(const SystemString& str)
: m_utf8(WideToUTF8(str)) {}
inline const std::string& utf8_str() {return m_utf8;}
};
class SystemStringView
{
std::wstring m_sys;
public:
SystemStringView(const std::string& str)
: m_sys(UTF8ToWide(str)) {}
inline const std::wstring& sys_str() {return m_sys;}
};
#ifndef _S
#define _S(val) L ## val
#endif
#else
typedef char SystemChar;
typedef std::string SystemString;
static inline void ToLower(SystemString& str)
{std::transform(str.begin(), str.end(), str.begin(), tolower);}
static inline void ToUpper(SystemString& str)
{std::transform(str.begin(), str.end(), str.begin(), toupper);}
class SystemUTF8View
{
const std::string& m_utf8;
public:
SystemUTF8View(const SystemString& str)
: m_utf8(str) {}
inline const std::string& utf8_str() {return m_utf8;}
};
class SystemStringView
{
const std::string& m_sys;
public:
SystemStringView(const std::string& str)
: m_sys(str) {}
inline const std::string& sys_str() {return m_sys;}
};
#ifndef _S
#define _S(val) val
#endif
#endif
/* Type-sensitive byte swappers */ /* Type-sensitive byte swappers */
template <typename T> template <typename T>
static inline T bswap16(T val) static inline T bswap16(T val)

View File

@ -1,6 +1,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "DiscBase.hpp" #include "NOD/DiscBase.hpp"
#include "IFileIO.hpp" #include "NOD/IFileIO.hpp"
#ifndef _WIN32 #ifndef _WIN32
#include <unistd.h> #include <unistd.h>
@ -49,9 +49,10 @@ void DiscBase::IPartition::parseFST(IPartReadStream& s)
} }
} }
void DiscBase::IPartition::Node::extractToDirectory(const std::string& basePath, bool force) void DiscBase::IPartition::Node::extractToDirectory(const SystemString& basePath, bool force)
{ {
std::string path = basePath + "/" + getName(); SystemStringView nameView(getName());
SystemString path = basePath + _S("/") + nameView.sys_str();
if (m_kind == NODE_DIRECTORY) if (m_kind == NODE_DIRECTORY)
{ {
if (mkdir(path.c_str(), 0755) && errno != EEXIST) if (mkdir(path.c_str(), 0755) && errno != EEXIST)
@ -72,34 +73,7 @@ void DiscBase::IPartition::Node::extractToDirectory(const std::string& basePath,
} }
} }
bool DiscBase::IPartition::_recursivePathOfNode(const std::string& basePath, void DiscBase::IPartition::extractToDirectory(const SystemString& path, bool force)
const Node& refNode,
const Node& curNode,
std::string& result)
{
std::string path = basePath + "/" + curNode.getName();
if (&refNode == &curNode)
{
result = path;
return true;
}
else if (curNode.m_kind == Node::NODE_DIRECTORY)
{
for (const Node& subnode : curNode)
if (_recursivePathOfNode(path, refNode, subnode, result))
break;
}
return false;
}
std::string DiscBase::IPartition::pathOfNode(const Node& node)
{
std::string result;
_recursivePathOfNode("", node, m_nodes[0], result);
return result;
}
void DiscBase::IPartition::extractToDirectory(const std::string& path, bool force)
{ {
struct stat theStat; struct stat theStat;
if (mkdir(path.c_str(), 0755) && errno != EEXIST) if (mkdir(path.c_str(), 0755) && errno != EEXIST)

View File

@ -1,4 +1,4 @@
#include "DiscGCN.hpp" #include "NOD/DiscGCN.hpp"
namespace NOD namespace NOD
{ {

View File

@ -1,15 +1,16 @@
#include <stdio.h> #include <stdio.h>
#include <stdexcept> #include <stdexcept>
#include "IDiscIO.hpp" #include "NOD/Util.hpp"
#include "NOD/IDiscIO.hpp"
namespace NOD namespace NOD
{ {
class DiscIOISO : public IDiscIO class DiscIOISO : public IDiscIO
{ {
std::string filepath; SystemString filepath;
public: public:
DiscIOISO(const std::string& fpin) DiscIOISO(const SystemString& fpin)
: filepath(fpin) {} : filepath(fpin) {}
class ReadStream : public IReadStream class ReadStream : public IReadStream
@ -27,10 +28,18 @@ public:
}; };
std::unique_ptr<IReadStream> beginReadStream(uint64_t offset) const std::unique_ptr<IReadStream> beginReadStream(uint64_t offset) const
{ {
#if NOD_UCS2
FILE* fp = wfopen(filepath.c_str(), L"rb");
#else
FILE* fp = fopen(filepath.c_str(), "rb"); FILE* fp = fopen(filepath.c_str(), "rb");
#endif
if (!fp) if (!fp)
{ {
throw std::runtime_error("Unable to open '" + filepath + "' for reading"); #if NOD_UCS2
fwprintf(stderr, L"Unable to open '%s' for reading\n", filepath.c_str());
#else
fprintf(stderr, "Unable to open '%s' for reading\n", filepath.c_str());
#endif
return std::unique_ptr<IReadStream>(); return std::unique_ptr<IReadStream>();
} }
fseeko(fp, offset, SEEK_SET); fseeko(fp, offset, SEEK_SET);
@ -50,10 +59,18 @@ public:
}; };
std::unique_ptr<IWriteStream> beginWriteStream(uint64_t offset) const std::unique_ptr<IWriteStream> beginWriteStream(uint64_t offset) const
{ {
#if NOD_UCS2
FILE* fp = wfopen(filepath.c_str(), L"wb");
#else
FILE* fp = fopen(filepath.c_str(), "wb"); FILE* fp = fopen(filepath.c_str(), "wb");
#endif
if (!fp) if (!fp)
{ {
throw std::runtime_error("Unable to open '" + filepath + "' for writing"); #if NOD_UCS2
fwprintf(stderr, L"Unable to open '%s' for writing\n", filepath.c_str());
#else
fprintf(stderr, "Unable to open '%s' for writing\n", filepath.c_str());
#endif
return std::unique_ptr<IWriteStream>(); return std::unique_ptr<IWriteStream>();
} }
fseeko(fp, offset, SEEK_SET); fseeko(fp, offset, SEEK_SET);
@ -61,7 +78,7 @@ public:
} }
}; };
std::unique_ptr<IDiscIO> NewDiscIOISO(const char* path) std::unique_ptr<IDiscIO> NewDiscIOISO(const SystemChar* path)
{ {
return std::unique_ptr<IDiscIO>(new DiscIOISO(path)); return std::unique_ptr<IDiscIO>(new DiscIOISO(path));
} }

View File

@ -1,15 +1,16 @@
#include <stdio.h> #include <stdio.h>
#include <stdexcept> #include <stdexcept>
#include "IDiscIO.hpp" #include "NOD/Util.hpp"
#include "NOD/IDiscIO.hpp"
namespace NOD namespace NOD
{ {
class DiscIOWBFS : public IDiscIO class DiscIOWBFS : public IDiscIO
{ {
std::string filepath; SystemString filepath;
public: public:
DiscIOWBFS(const std::string& fpin) DiscIOWBFS(const SystemString& fpin)
: filepath(fpin) {} : filepath(fpin) {}
class ReadStream : public IReadStream class ReadStream : public IReadStream
@ -27,10 +28,18 @@ public:
}; };
std::unique_ptr<IReadStream> beginReadStream(uint64_t offset) const std::unique_ptr<IReadStream> beginReadStream(uint64_t offset) const
{ {
#if NOD_UCS2
FILE* fp = wfopen(filepath.c_str(), L"rb");
#else
FILE* fp = fopen(filepath.c_str(), "rb"); FILE* fp = fopen(filepath.c_str(), "rb");
#endif
if (!fp) if (!fp)
{ {
throw std::runtime_error("Unable to open '" + filepath + "' for reading"); #if NOD_UCS2
fwprintf(stderr, L"Unable to open '%s' for reading\n", filepath.c_str());
#else
fprintf(stderr, "Unable to open '%s' for reading\n", filepath.c_str());
#endif
return std::unique_ptr<IReadStream>(); return std::unique_ptr<IReadStream>();
} }
fseeko(fp, offset, SEEK_SET); fseeko(fp, offset, SEEK_SET);
@ -50,10 +59,18 @@ public:
}; };
std::unique_ptr<IWriteStream> beginWriteStream(uint64_t offset) const std::unique_ptr<IWriteStream> beginWriteStream(uint64_t offset) const
{ {
#if NOD_UCS2
FILE* fp = wfopen(filepath.c_str(), L"wb");
#else
FILE* fp = fopen(filepath.c_str(), "wb"); FILE* fp = fopen(filepath.c_str(), "wb");
#endif
if (!fp) if (!fp)
{ {
throw std::runtime_error("Unable to open '" + filepath + "' for writing"); #if NOD_UCS2
fwprintf(stderr, L"Unable to open '%s' for writing\n", filepath.c_str());
#else
fprintf(stderr, "Unable to open '%s' for writing\n", filepath.c_str());
#endif
return std::unique_ptr<IWriteStream>(); return std::unique_ptr<IWriteStream>();
} }
fseeko(fp, offset, SEEK_SET); fseeko(fp, offset, SEEK_SET);
@ -61,7 +78,7 @@ public:
} }
}; };
std::unique_ptr<IDiscIO> NewDiscIOWBFS(const char* path) std::unique_ptr<IDiscIO> NewDiscIOWBFS(const SystemChar* path)
{ {
return std::unique_ptr<IDiscIO>(new DiscIOWBFS(path)); return std::unique_ptr<IDiscIO>(new DiscIOWBFS(path));
} }

View File

@ -1,7 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "DiscWii.hpp" #include "NOD/DiscWii.hpp"
#include "aes.hpp" #include "NOD/aes.hpp"
namespace NOD namespace NOD
{ {

View File

@ -2,7 +2,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdexcept> #include <stdexcept>
#include "IFileIO.hpp" #include "NOD/Util.hpp"
#include "NOD/IFileIO.hpp"
/* Macros for min/max */ /* Macros for min/max */
#define MIN(a,b) (((a)<(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b))
@ -13,14 +14,18 @@ namespace NOD
class FileIOFILE : public IFileIO class FileIOFILE : public IFileIO
{ {
std::string m_path; SystemString m_path;
public: public:
FileIOFILE(const std::string& path) FileIOFILE(const SystemString& path)
: m_path(path) {} : m_path(path) {}
uint64_t size() uint64_t size()
{ {
#if NOD_UCS2
FILE* fp = wfopen(m_path.c_str(), L"rb");
#else
FILE* fp = fopen(m_path.c_str(), "rb"); FILE* fp = fopen(m_path.c_str(), "rb");
#endif
if (!fp) if (!fp)
return 0; return 0;
fseeko(fp, 0, SEEK_END); fseeko(fp, 0, SEEK_END);
@ -33,11 +38,21 @@ public:
{ {
FILE* fp; FILE* fp;
uint8_t buf[0x7c00]; uint8_t buf[0x7c00];
WriteStream(const std::string& path) WriteStream(const SystemString& path)
{ {
#if NOD_UCS2
fp = wfopen(path.c_str(), L"wb");
#else
fp = fopen(path.c_str(), "wb"); fp = fopen(path.c_str(), "wb");
#endif
if (!fp) if (!fp)
throw std::runtime_error("unable to open '" + path + "' for writing"); {
#if NOD_UCS2
throw std::runtime_error("Unable to open '" + WideToUTF8(path) + "' for writing");
#else
throw std::runtime_error("Unable to open '" + path + "' for writing");
#endif
}
} }
~WriteStream() {fclose(fp);} ~WriteStream() {fclose(fp);}
uint64_t write(void* buf, uint64_t length) uint64_t write(void* buf, uint64_t length)
@ -66,11 +81,21 @@ public:
{ {
FILE* fp; FILE* fp;
uint8_t buf[0x7c00]; uint8_t buf[0x7c00];
ReadStream(const std::string& path) ReadStream(const SystemString& path)
{ {
#if NOD_UCS2
fp = wfopen(path.c_str(), L"rb");
#else
fp = fopen(path.c_str(), "rb"); fp = fopen(path.c_str(), "rb");
#endif
if (!fp) if (!fp)
throw std::runtime_error("unable to open '" + path + "' for reading"); {
#if NOD_UCS2
throw std::runtime_error("Unable to open '" + WideToUTF8(path) + "' for reading");
#else
throw std::runtime_error("Unable to open '" + path + "' for reading");
#endif
}
} }
~ReadStream() {fclose(fp);} ~ReadStream() {fclose(fp);}
uint64_t read(void* buf, uint64_t length) uint64_t read(void* buf, uint64_t length)
@ -95,7 +120,7 @@ public:
{return std::unique_ptr<IReadStream>(new ReadStream(m_path));} {return std::unique_ptr<IReadStream>(new ReadStream(m_path));}
}; };
std::unique_ptr<IFileIO> NewFileIO(const std::string& path) std::unique_ptr<IFileIO> NewFileIO(const SystemString& path)
{ {
return std::unique_ptr<IFileIO>(new FileIOFILE(path)); return std::unique_ptr<IFileIO>(new FileIOFILE(path));
} }

View File

@ -1,4 +1,4 @@
#include "IFileIO.hpp" #include "NOD/IFileIO.hpp"
namespace NOD namespace NOD
{ {

View File

@ -1,19 +1,23 @@
#include <stdio.h> #include <stdio.h>
#include "NODLib.hpp" #include "NOD/NOD.hpp"
#include "DiscBase.hpp" #include "NOD/DiscBase.hpp"
namespace NOD namespace NOD
{ {
std::unique_ptr<IDiscIO> NewDiscIOISO(const char* path); std::unique_ptr<IDiscIO> NewDiscIOISO(const SystemChar* path);
std::unique_ptr<IDiscIO> NewDiscIOWBFS(const char* path); std::unique_ptr<IDiscIO> NewDiscIOWBFS(const SystemChar* path);
std::unique_ptr<DiscBase> OpenDiscFromImage(const char* path, bool& isWii) std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path, bool& isWii)
{ {
/* Temporary file handle to determine image type */ /* Temporary file handle to determine image type */
FILE* fp = fopen(path, "rb"); FILE* fp = fopen(path, "rb");
if (!fp) if (!fp)
{ {
throw std::runtime_error("Unable to open '" + std::string(path) + "'"); #if NOD_UCS2
fwprintf(stderr, L"Unable to open '%s'\n", path);
#else
fprintf(stderr, "Unable to open '%s'\n", path);
#endif
return std::unique_ptr<DiscBase>(); return std::unique_ptr<DiscBase>();
} }
@ -47,13 +51,18 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(const char* path, bool& isWii)
fclose(fp); fclose(fp);
discIO = NewDiscIOISO(path); discIO = NewDiscIOISO(path);
} }
else
fclose(fp);
} }
} }
if (!discIO) if (!discIO)
{ {
fclose(fp); #if NOD_UCS2
throw std::runtime_error("'" + std::string(path) + "' is not a valid image"); fwprintf(stderr, L"'%s' is not a valid image\n", path);
#else
fprintf(stderr, "'%s' is not a valid image\n", path);
#endif
return std::unique_ptr<DiscBase>(); return std::unique_ptr<DiscBase>();
} }
@ -64,7 +73,7 @@ std::unique_ptr<DiscBase> OpenDiscFromImage(const char* path, bool& isWii)
} }
std::unique_ptr<DiscBase> OpenDiscFromImage(const char* path) std::unique_ptr<DiscBase> OpenDiscFromImage(const SystemChar* path)
{ {
bool isWii; bool isWii;
return OpenDiscFromImage(path, isWii); return OpenDiscFromImage(path, isWii);

20
lib/WideStringConvert.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "NOD/NOD.hpp"
#include <locale>
#include <codecvt>
namespace NOD
{
std::string WideToUTF8(const std::wstring& src)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.to_bytes(src);
}
std::wstring UTF8ToWide(const std::string& src)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.from_bytes(src);
}
}

View File

@ -1,4 +1,4 @@
#include "aes.hpp" #include "NOD/aes.hpp"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <cpuid.h> #include <cpuid.h>

View File

@ -9,7 +9,6 @@ QMAKE_CXXFLAGS += -maes
INCLUDEPATH += ../include INCLUDEPATH += ../include
SOURCES += \ SOURCES += \
NODLib.cpp \
FileIOFILE.cpp \ FileIOFILE.cpp \
FileIOMEM.cpp \ FileIOMEM.cpp \
DiscBase.cpp \ DiscBase.cpp \
@ -17,5 +16,7 @@ SOURCES += \
DiscWii.cpp \ DiscWii.cpp \
DiscIOWBFS.cpp \ DiscIOWBFS.cpp \
DiscIOISO.cpp \ DiscIOISO.cpp \
aes.cpp aes.cpp \
WideStringConvert.cpp \
NOD.cpp