Use virtual classes instead of templates for file interfaces

For convenience.
This commit is contained in:
zhupengfei
2020-08-01 09:47:44 +08:00
parent e861d84b72
commit 1f91cbdaec
11 changed files with 111 additions and 212 deletions
+23 -36
View File
@@ -98,18 +98,25 @@ std::vector<u8> SDMCDecryptor::DecryptFile(const std::string& source) const {
return data;
}
SDMCFile::SDMCFile() = default;
struct SDMCFile::Impl {
CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption aes;
std::array<u8, 16> original_ctr;
std::array<u8, 16> key;
};
SDMCFile::SDMCFile(std::string root_folder, const std::string& filename, const char openmode[],
int flags) {
impl = std::make_unique<Impl>();
if (root_folder.back() == '/' || root_folder.back() == '\\') {
// Remove '/' or '\' character at the end as we will add them back when combining path
root_folder.erase(root_folder.size() - 1);
}
original_ctr = GetFileCTR(filename);
key = Key::GetNormalKey(Key::SDKey);
// aes.SetKeyWithIV(key.data(), key.size(), original_ctr.data());
impl->original_ctr = GetFileCTR(filename);
impl->key = Key::GetNormalKey(Key::SDKey);
impl->aes.SetKeyWithIV(impl->key.data(), impl->key.size(), impl->original_ctr.data());
Open(root_folder + filename, openmode, flags);
}
@@ -118,46 +125,26 @@ SDMCFile::~SDMCFile() {
Close();
}
SDMCFile::SDMCFile(SDMCFile&& other) {
Swap(other);
std::size_t SDMCFile::Read(char* data, std::size_t length) {
const std::size_t length_read = FileUtil::IOFile::Read(data, length);
DecryptData(reinterpret_cast<u8*>(data), length_read);
return length_read;
}
SDMCFile& SDMCFile::operator=(SDMCFile&& other) {
Swap(other);
return *this;
}
void SDMCFile::Swap(SDMCFile& other) {
file.Swap(other.file);
std::swap(original_ctr, other.original_ctr);
std::swap(key, other.key);
}
bool SDMCFile::Open(const std::string& filename, const char openmode[], int flags) {
return file.Open(filename, openmode, flags);
}
bool SDMCFile::Close() {
return file.Close();
}
u64 SDMCFile::GetSize() const {
return file.GetSize();
std::size_t SDMCFile::Write(const char* data, std::size_t length) {
UNREACHABLE_MSG("Cannot write to a SDMCFile");
}
bool SDMCFile::Seek(s64 off, int origin) {
return file.Seek(off, origin);
}
u64 SDMCFile::Tell() const {
return file.Tell();
if (!FileUtil::IOFile::Seek(off, origin)) {
return false;
}
impl->aes.Seek(Tell());
return true;
}
void SDMCFile::DecryptData(u8* data, std::size_t size) {
CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption aes;
aes.SetKeyWithIV(key.data(), key.size(), original_ctr.data());
aes.Seek(Tell() - size);
aes.ProcessData(data, data, size);
impl->aes.ProcessData(data, data, size);
}
} // namespace Core