summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-10-09 16:56:32 -0400
committerGravatar GitHub2018-10-09 16:56:32 -0400
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.gz
yuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.tar.xz
yuzu-141a0d938660ae8b94ae2a4259db7f4f4d136ca0.zip
Merge pull request #1462 from lioncash/move
ips_layer: Minor miscellaneous changes
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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
6#include <cstring>
7#include <map>
5#include <sstream> 8#include <sstream>
6#include "common/assert.h" 9#include <string>
10#include <utility>
11
7#include "common/hex_util.h" 12#include "common/hex_util.h"
13#include "common/logging/log.h"
8#include "common/swap.h" 14#include "common/swap.h"
9#include "core/file_sys/ips_layer.h" 15#include "core/file_sys/ips_layer.h"
10#include "core/file_sys/vfs_vector.h" 16#include "core/file_sys/vfs_vector.h"
@@ -17,22 +23,48 @@ enum class IPSFileType {
17 Error, 23 Error,
18}; 24};
19 25
20constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{ 26constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{{
21 std::pair{"\\a", "\a"}, {"\\b", "\b"}, {"\\f", "\f"}, {"\\n", "\n"}, 27 {"\\a", "\a"},
22 {"\\r", "\r"}, {"\\t", "\t"}, {"\\v", "\v"}, {"\\\\", "\\"}, 28 {"\\b", "\b"},
23 {"\\\'", "\'"}, {"\\\"", "\""}, {"\\\?", "\?"}, 29 {"\\f", "\f"},
24}; 30 {"\\n", "\n"},
31 {"\\r", "\r"},
32 {"\\t", "\t"},
33 {"\\v", "\v"},
34 {"\\\\", "\\"},
35 {"\\\'", "\'"},
36 {"\\\"", "\""},
37 {"\\\?", "\?"},
38}};
25 39
26static IPSFileType IdentifyMagic(const std::vector<u8>& magic) { 40static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
27 if (magic.size() != 5) 41 if (magic.size() != 5) {
28 return IPSFileType::Error; 42 return IPSFileType::Error;
29 if (magic == std::vector<u8>{'P', 'A', 'T', 'C', 'H'}) 43 }
44
45 constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}};
46 if (std::equal(magic.begin(), magic.end(), patch_magic.begin())) {
30 return IPSFileType::IPS; 47 return IPSFileType::IPS;
31 if (magic == std::vector<u8>{'I', 'P', 'S', '3', '2'}) 48 }
49
50 constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}};
51 if (std::equal(magic.begin(), magic.end(), ips32_magic.begin())) {
32 return IPSFileType::IPS32; 52 return IPSFileType::IPS32;
53 }
54
33 return IPSFileType::Error; 55 return IPSFileType::Error;
34} 56}
35 57
58static bool IsEOF(IPSFileType type, const std::vector<u8>& data) {
59 constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}};
60 if (type == IPSFileType::IPS && std::equal(data.begin(), data.end(), eof.begin())) {
61 return true;
62 }
63
64 constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}};
65 return type == IPSFileType::IPS32 && std::equal(data.begin(), data.end(), eeof.begin());
66}
67
36VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) { 68VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
37 if (in == nullptr || ips == nullptr) 69 if (in == nullptr || ips == nullptr)
38 return nullptr; 70 return nullptr;
@@ -47,8 +79,7 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
47 u64 offset = 5; // After header 79 u64 offset = 5; // After header
48 while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) { 80 while (ips->Read(temp.data(), temp.size(), offset) == temp.size()) {
49 offset += temp.size(); 81 offset += temp.size();
50 if (type == IPSFileType::IPS32 && temp == std::vector<u8>{'E', 'E', 'O', 'F'} || 82 if (IsEOF(type, temp)) {
51 type == IPSFileType::IPS && temp == std::vector<u8>{'E', 'O', 'F'}) {
52 break; 83 break;
53 } 84 }
54 85
@@ -88,11 +119,20 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
88 } 119 }
89 } 120 }
90 121
91 if (temp != std::vector<u8>{'E', 'E', 'O', 'F'} && temp != std::vector<u8>{'E', 'O', 'F'}) 122 if (!IsEOF(type, temp)) {
92 return nullptr; 123 return nullptr;
93 return std::make_shared<VectorVfsFile>(in_data, in->GetName(), in->GetContainingDirectory()); 124 }
125
126 return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(),
127 in->GetContainingDirectory());
94} 128}
95 129
130struct IPSwitchCompiler::IPSwitchPatch {
131 std::string name;
132 bool enabled;
133 std::map<u32, std::vector<u8>> records;
134};
135
96IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) { 136IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) {
97 Parse(); 137 Parse();
98} 138}
@@ -291,7 +331,8 @@ VirtualFile IPSwitchCompiler::Apply(const VirtualFile& in) const {
291 } 331 }
292 } 332 }
293 333
294 return std::make_shared<VectorVfsFile>(in_data, in->GetName(), in->GetContainingDirectory()); 334 return std::make_shared<VectorVfsFile>(std::move(in_data), in->GetName(),
335 in->GetContainingDirectory());
295} 336}
296 337
297} // namespace FileSys 338} // 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <memory> 8#include <memory>
9#include <vector>
8 10
11#include "common/common_types.h"
9#include "core/file_sys/vfs.h" 12#include "core/file_sys/vfs.h"
10 13
11namespace FileSys { 14namespace FileSys {
@@ -22,17 +25,13 @@ public:
22 VirtualFile Apply(const VirtualFile& in) const; 25 VirtualFile Apply(const VirtualFile& in) const;
23 26
24private: 27private:
28 struct IPSwitchPatch;
29
25 void ParseFlag(const std::string& flag); 30 void ParseFlag(const std::string& flag);
26 void Parse(); 31 void Parse();
27 32
28 bool valid = false; 33 bool valid = false;
29 34
30 struct IPSwitchPatch {
31 std::string name;
32 bool enabled;
33 std::map<u32, std::vector<u8>> records;
34 };
35
36 VirtualFile patch_text; 35 VirtualFile patch_text;
37 std::vector<IPSwitchPatch> patches; 36 std::vector<IPSwitchPatch> patches;
38 std::array<u8, 0x20> nso_build_id{}; 37 std::array<u8, 0x20> nso_build_id{};