diff options
| author | 2018-10-09 16:56:32 -0400 | |
|---|---|---|
| committer | 2018-10-09 16:56:32 -0400 | |
| commit | 141a0d938660ae8b94ae2a4259db7f4f4d136ca0 (patch) | |
| tree | f82c21fc6999506ec6efe8fd9e47ab1f6b33f2af /src | |
| parent | Merge pull request #1455 from ogniK5377/smo-softlockfix (diff) | |
| parent | ips_layer: Avoid constructing std::vector instances where not necessary (diff) | |
| download | yuzu-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.cpp | 69 | ||||
| -rw-r--r-- | src/core/file_sys/ips_layer.h | 11 |
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 | ||
| 20 | constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{ | 26 | constexpr 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 | ||
| 26 | static IPSFileType IdentifyMagic(const std::vector<u8>& magic) { | 40 | static 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 | ||
| 58 | static 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 | |||
| 36 | VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) { | 68 | VirtualFile 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 | ||
| 130 | struct IPSwitchCompiler::IPSwitchPatch { | ||
| 131 | std::string name; | ||
| 132 | bool enabled; | ||
| 133 | std::map<u32, std::vector<u8>> records; | ||
| 134 | }; | ||
| 135 | |||
| 96 | IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) { | 136 | IPSwitchCompiler::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 | ||
| 11 | namespace FileSys { | 14 | namespace FileSys { |
| @@ -22,17 +25,13 @@ public: | |||
| 22 | VirtualFile Apply(const VirtualFile& in) const; | 25 | VirtualFile Apply(const VirtualFile& in) const; |
| 23 | 26 | ||
| 24 | private: | 27 | private: |
| 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{}; |