Merge pull request #1462 from lioncash/move
ips_layer: Minor miscellaneous changes
This commit is contained in:
commit
141a0d9386
|
@ -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{};
|
||||||
|
|
Reference in New Issue