Merge pull request #1462 from lioncash/move

ips_layer: Minor miscellaneous changes
master
bunnei 2018-10-09 16:56:32 +07:00 committed by GitHub
commit 141a0d9386
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 20 deletions

@ -2,9 +2,15 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm>
#include <cstring>
#include <map>
#include <sstream> #include <sstream>
#include "common/assert.h" #include <string>
#include <utility>
#include "common/hex_util.h" #include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/file_sys/ips_layer.h" #include "core/file_sys/ips_layer.h"
#include "core/file_sys/vfs_vector.h" #include "core/file_sys/vfs_vector.h"
@ -17,22 +23,48 @@ enum class IPSFileType {
Error, Error,
}; };
constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{ constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{{
std::pair{"\\a", "\a"}, {"\\b", "\b"}, {"\\f", "\f"}, {"\\n", "\n"}, {"\\a", "\a"},
{"\\r", "\r"}, {"\\t", "\t"}, {"\\v", "\v"}, {"\\\\", "\\"}, {"\\b", "\b"},
{"\\\'", "\'"}, {"\\\"", "\""}, {"\\\?", "\?"}, {"\\f", "\f"},
}; {"\\n", "\n"},
{"\\r", "\r"},
{"\\t", "\t"},
{"\\v", "\v"},
{"\\\\", "\\"},
{"\\\'", "\'"},
{"\\\"", "\""},
{"\\\?", "\?"},
}};
static IPSFileType IdentifyMagic(const std::vector<u8>& magic) { static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
if (magic.size() != 5) if (magic.size() != 5) {
return IPSFileType::Error; return IPSFileType::Error;
if (magic == std::vector<u8>{'P', 'A', 'T', 'C', 'H'}) }
constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}};
if (std::equal(magic.begin(), magic.end(), patch_magic.begin())) {
return IPSFileType::IPS; return IPSFileType::IPS;
if (magic == std::vector<u8>{'I', 'P', 'S', '3', '2'}) }
constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}};
if (std::equal(magic.begin(), magic.end(), ips32_magic.begin())) {
return IPSFileType::IPS32; return IPSFileType::IPS32;
}
return IPSFileType::Error; return IPSFileType::Error;
} }
static bool IsEOF(IPSFileType type, const std::vector<u8>& data) {
constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}};
if (type == IPSFileType::IPS && std::equal(data.begin(), data.end(), eof.begin())) {
return true;
}
constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}};
return type == IPSFileType::IPS32 && std::equal(data.begin(), data.end(), eeof.begin());
}
VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) { VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
if (in == nullptr || ips == nullptr) if (in == nullptr || ips == nullptr)
return nullptr; return nullptr;
@ -47,8 +79,7 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
u64 offset = 5; // After header u64 offset = 5; // After header
while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) { while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) {
offset += temp.size(); offset += temp.size();
if (type == IPSFileType::IPS32 && temp == std::vector<u8>{'E', 'E', 'O', 'F'} || if (IsEOF(type, temp)) {
type == IPSFileType::IPS && temp == std::vector<u8>{'E', 'O', 'F'}) {
break; break;
} }
@ -88,11 +119,20 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
} }
} }
if (temp != std::vector<u8>{'E', 'E', 'O', 'F'} && temp != std::vector<u8>{'E', 'O', 'F'}) if (!IsEOF(type, temp)) {
return nullptr; return nullptr;
return std::make_shared<VectorVfsFile>(in_data, in->GetName(), in->GetContainingDirectory()); }
return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(),
in->GetContainingDirectory());
} }
struct IPSwitchCompiler::IPSwitchPatch {
std::string name;
bool enabled;
std::map<u32, std::vector<u8>> records;
};
IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) { IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) {
Parse(); Parse();
} }
@ -291,7 +331,8 @@ VirtualFile IPSwitchCompiler::Apply(const VirtualFile& in) const {
} }
} }
return std::make_shared<VectorVfsFile>(in_data, in->GetName(), in->GetContainingDirectory()); return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(),
in->GetContainingDirectory());
} }
} // namespace FileSys } // namespace FileSys

@ -4,8 +4,11 @@
#pragma once #pragma once
#include <array>
#include <memory> #include <memory>
#include <vector>
#include "common/common_types.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
namespace FileSys { namespace FileSys {
@ -22,17 +25,13 @@ public:
VirtualFile Apply(const VirtualFile& in) const; VirtualFile Apply(const VirtualFile& in) const;
private: private:
struct IPSwitchPatch;
void ParseFlag(const std::string& flag); void ParseFlag(const std::string& flag);
void Parse(); void Parse();
bool valid = false; bool valid = false;
struct IPSwitchPatch {
std::string name;
bool enabled;
std::map<u32, std::vector<u8>> records;
};
VirtualFile patch_text; VirtualFile patch_text;
std::vector<IPSwitchPatch> patches; std::vector<IPSwitchPatch> patches;
std::array<u8, 0x20> nso_build_id{}; std::array<u8, 0x20> nso_build_id{};