summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-10-09 22:56:32 +0200
committerGitHub <noreply@github.com>2018-10-09 22:56:32 +0200
commit141a0d938660ae8b94ae2a4259db7f4f4d136ca0 (patch)
treef82c21fc6999506ec6efe8fd9e47ab1f6b33f2af /src
parentMerge pull request #1455 from ogniK5377/smo-softlockfix (diff)
parentips_layer: Avoid constructing std::vector instances where not necessary (diff)
downloadyuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.tar
yuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.tar.gz
yuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.tar.bz2
yuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.tar.lz
yuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.tar.xz
yuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.tar.zst
yuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.zip
Diffstat (limited to 'src')
-rw-r--r--src/core/file_sys/ips_layer.cpp69
-rw-r--r--src/core/file_sys/ips_layer.h11
2 files changed, 60 insertions, 20 deletions
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp
index 0cadbc375..6c072d0a3 100644
--- a/src/core/file_sys/ips_layer.cpp
+++ b/src/core/file_sys/ips_layer.cpp
@@ -2,9 +2,15 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
+#include <cstring>
+#include <map>
#include <sstream>
-#include "common/assert.h"
+#include <string>
+#include <utility>
+
#include "common/hex_util.h"
+#include "common/logging/log.h"
#include "common/swap.h"
#include "core/file_sys/ips_layer.h"
#include "core/file_sys/vfs_vector.h"
@@ -17,22 +23,48 @@ enum class IPSFileType {
Error,
};
-constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{
- std::pair{"\\a", "\a"}, {"\\b", "\b"}, {"\\f", "\f"}, {"\\n", "\n"},
- {"\\r", "\r"}, {"\\t", "\t"}, {"\\v", "\v"}, {"\\\\", "\\"},
- {"\\\'", "\'"}, {"\\\"", "\""}, {"\\\?", "\?"},
-};
+constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{{
+ {"\\a", "\a"},
+ {"\\b", "\b"},
+ {"\\f", "\f"},
+ {"\\n", "\n"},
+ {"\\r", "\r"},
+ {"\\t", "\t"},
+ {"\\v", "\v"},
+ {"\\\\", "\\"},
+ {"\\\'", "\'"},
+ {"\\\"", "\""},
+ {"\\\?", "\?"},
+}};
static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
- if (magic.size() != 5)
+ if (magic.size() != 5) {
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;
- 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::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) {
if (in == nullptr || ips == nullptr)
return nullptr;
@@ -47,8 +79,7 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
u64 offset = 5; // After header
while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) {
offset += temp.size();
- if (type == IPSFileType::IPS32 && temp == std::vector<u8>{'E', 'E', 'O', 'F'} ||
- type == IPSFileType::IPS && temp == std::vector<u8>{'E', 'O', 'F'}) {
+ if (IsEOF(type, temp)) {
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 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_)) {
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
diff --git a/src/core/file_sys/ips_layer.h b/src/core/file_sys/ips_layer.h
index 57da00da8..450b2f71e 100644
--- a/src/core/file_sys/ips_layer.h
+++ b/src/core/file_sys/ips_layer.h
@@ -4,8 +4,11 @@
#pragma once
+#include <array>
#include <memory>
+#include <vector>
+#include "common/common_types.h"
#include "core/file_sys/vfs.h"
namespace FileSys {
@@ -22,17 +25,13 @@ public:
VirtualFile Apply(const VirtualFile& in) const;
private:
+ struct IPSwitchPatch;
+
void ParseFlag(const std::string& flag);
void Parse();
bool valid = false;
- struct IPSwitchPatch {
- std::string name;
- bool enabled;
- std::map<u32, std::vector<u8>> records;
- };
-
VirtualFile patch_text;
std::vector<IPSwitchPatch> patches;
std::array<u8, 0x20> nso_build_id{};