diff options
| author | 2018-10-01 17:17:08 -0400 | |
|---|---|---|
| committer | 2018-10-04 11:34:36 -0400 | |
| commit | 70bd2bb1d3aec23fc052c9612f9e530c1a2de72d (patch) | |
| tree | 309d313d8182778919cafff884fd962267d2b38c | |
| parent | ips_layer: Add support for escape sequences and midline comments (diff) | |
| download | yuzu-70bd2bb1d3aec23fc052c9612f9e530c1a2de72d.tar.gz yuzu-70bd2bb1d3aec23fc052c9612f9e530c1a2de72d.tar.xz yuzu-70bd2bb1d3aec23fc052c9612f9e530c1a2de72d.zip | |
ips_layer: Deduplicate resource usage
Diffstat (limited to '')
| -rw-r--r-- | src/common/hex_util.cpp | 2 | ||||
| -rw-r--r-- | src/common/hex_util.h | 2 | ||||
| -rw-r--r-- | src/core/file_sys/ips_layer.cpp | 48 | ||||
| -rw-r--r-- | src/core/file_sys/ips_layer.h | 14 | ||||
| -rw-r--r-- | src/core/file_sys/patch_manager.cpp | 6 |
5 files changed, 39 insertions, 33 deletions
diff --git a/src/common/hex_util.cpp b/src/common/hex_util.cpp index e516e5bbd..5b63f9e81 100644 --- a/src/common/hex_util.cpp +++ b/src/common/hex_util.cpp | |||
| @@ -30,7 +30,7 @@ std::vector<u8> HexStringToVector(std::string_view str, bool little_endian) { | |||
| 30 | return out; | 30 | return out; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | std::string HexVectorToString(std::vector<u8> vector, bool upper) { | 33 | std::string HexVectorToString(const std::vector<u8>& vector, bool upper) { |
| 34 | std::string out; | 34 | std::string out; |
| 35 | for (u8 c : vector) | 35 | for (u8 c : vector) |
| 36 | out += fmt::format(upper ? "{:02X}" : "{:02x}", c); | 36 | out += fmt::format(upper ? "{:02X}" : "{:02x}", c); |
diff --git a/src/common/hex_util.h b/src/common/hex_util.h index 0b7d3592a..68f003cb6 100644 --- a/src/common/hex_util.h +++ b/src/common/hex_util.h | |||
| @@ -30,7 +30,7 @@ std::array<u8, Size> HexStringToArray(std::string_view str) { | |||
| 30 | return out; | 30 | return out; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | std::string HexVectorToString(std::vector<u8> vector, bool upper = true); | 33 | std::string HexVectorToString(const std::vector<u8>& vector, bool upper = true); |
| 34 | 34 | ||
| 35 | template <std::size_t Size> | 35 | template <std::size_t Size> |
| 36 | std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) { | 36 | std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) { |
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp index 6c5535f83..abe3dcf62 100644 --- a/src/core/file_sys/ips_layer.cpp +++ b/src/core/file_sys/ips_layer.cpp | |||
| @@ -17,9 +17,10 @@ enum class IPSFileType { | |||
| 17 | Error, | 17 | Error, |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | const std::map<const char*, const char*> ESCAPE_CHARACTER_MAP{ | 20 | constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{ |
| 21 | {"\\a", "\a"}, {"\\b", "\b"}, {"\\f", "\f"}, {"\\n", "\n"}, {"\\r", "\r"}, {"\\t", "\t"}, | 21 | std::pair{"\\a", "\a"}, {"\\b", "\b"}, {"\\f", "\f"}, {"\\n", "\n"}, |
| 22 | {"\\v", "\v"}, {"\\\\", "\\"}, {"\\\'", "\'"}, {"\\\"", "\""}, {"\\\?", "\?"}, | 22 | {"\\r", "\r"}, {"\\t", "\t"}, {"\\v", "\v"}, {"\\\\", "\\"}, |
| 23 | {"\\\'", "\'"}, {"\\\"", "\""}, {"\\\?", "\?"}, | ||
| 23 | }; | 24 | }; |
| 24 | 25 | ||
| 25 | static IPSFileType IdentifyMagic(const std::vector<u8>& magic) { | 26 | static IPSFileType IdentifyMagic(const std::vector<u8>& magic) { |
| @@ -92,12 +93,12 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) { | |||
| 92 | return std::make_shared<VectorVfsFile>(in_data, in->GetName(), in->GetContainingDirectory()); | 93 | return std::make_shared<VectorVfsFile>(in_data, in->GetName(), in->GetContainingDirectory()); |
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) | 96 | IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) { |
| 96 | : valid(false), patch_text(std::move(patch_text_)), nso_build_id{}, is_little_endian(false), | ||
| 97 | offset_shift(0), print_values(false), last_comment("") { | ||
| 98 | Parse(); | 97 | Parse(); |
| 99 | } | 98 | } |
| 100 | 99 | ||
| 100 | IPSwitchCompiler::~IPSwitchCompiler() = default; | ||
| 101 | |||
| 101 | std::array<u8, 32> IPSwitchCompiler::GetBuildID() const { | 102 | std::array<u8, 32> IPSwitchCompiler::GetBuildID() const { |
| 102 | return nso_build_id; | 103 | return nso_build_id; |
| 103 | } | 104 | } |
| @@ -106,7 +107,7 @@ bool IPSwitchCompiler::IsValid() const { | |||
| 106 | return valid; | 107 | return valid; |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | static bool StartsWith(const std::string& base, const std::string& check) { | 110 | static bool StartsWith(std::string_view base, std::string_view check) { |
| 110 | return base.size() >= check.size() && base.substr(0, check.size()) == check; | 111 | return base.size() >= check.size() && base.substr(0, check.size()) == check; |
| 111 | } | 112 | } |
| 112 | 113 | ||
| @@ -128,21 +129,22 @@ void IPSwitchCompiler::Parse() { | |||
| 128 | s.write(reinterpret_cast<const char*>(bytes.data()), bytes.size()); | 129 | s.write(reinterpret_cast<const char*>(bytes.data()), bytes.size()); |
| 129 | 130 | ||
| 130 | std::vector<std::string> lines; | 131 | std::vector<std::string> lines; |
| 131 | std::string line; | 132 | std::string stream_line; |
| 132 | while (std::getline(s, line)) { | 133 | while (std::getline(s, stream_line)) { |
| 133 | // Remove a trailing \r | 134 | // Remove a trailing \r |
| 134 | if (!line.empty() && line[line.size() - 1] == '\r') | 135 | if (!stream_line.empty() && stream_line.back() == '\r') |
| 135 | line = line.substr(0, line.size() - 1); | 136 | stream_line.pop_back(); |
| 136 | lines.push_back(line); | 137 | lines.push_back(std::move(stream_line)); |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | for (std::size_t i = 0; i < lines.size(); ++i) { | 140 | for (std::size_t i = 0; i < lines.size(); ++i) { |
| 140 | auto line = lines[i]; | 141 | auto line = lines[i]; |
| 141 | 142 | ||
| 142 | // Remove midline comments | 143 | // Remove midline comments |
| 143 | if (!StartsWith(line, "//") && line.find("//") != std::string::npos) { | 144 | const auto comment_index = line.find("//"); |
| 144 | last_comment = line.substr(line.find("//") + 2); | 145 | if (!StartsWith(line, "//") && comment_index != std::string::npos) { |
| 145 | line = line.substr(0, line.find("//")); | 146 | last_comment = line.substr(comment_index + 2); |
| 147 | line = line.substr(0, comment_index); | ||
| 146 | } | 148 | } |
| 147 | 149 | ||
| 148 | if (StartsWith(line, "@stop")) { | 150 | if (StartsWith(line, "@stop")) { |
| @@ -191,28 +193,28 @@ void IPSwitchCompiler::Parse() { | |||
| 191 | while (true) { | 193 | while (true) { |
| 192 | if (i + 1 >= lines.size()) | 194 | if (i + 1 >= lines.size()) |
| 193 | break; | 195 | break; |
| 194 | line = lines[++i]; | 196 | const auto patch_line = lines[++i]; |
| 195 | 197 | ||
| 196 | // 11 - 8 hex digit offset + space + minimum two digit overwrite val | 198 | // 11 - 8 hex digit offset + space + minimum two digit overwrite val |
| 197 | if (line.length() < 11) | 199 | if (patch_line.length() < 11) |
| 198 | break; | 200 | break; |
| 199 | auto offset = std::stoul(line.substr(0, 8), nullptr, 16); | 201 | auto offset = std::stoul(patch_line.substr(0, 8), nullptr, 16); |
| 200 | offset += offset_shift; | 202 | offset += offset_shift; |
| 201 | 203 | ||
| 202 | std::vector<u8> replace; | 204 | std::vector<u8> replace; |
| 203 | // 9 - first char of replacement val | 205 | // 9 - first char of replacement val |
| 204 | if (line[9] == '\"') { | 206 | if (patch_line[9] == '\"') { |
| 205 | // string replacement | 207 | // string replacement |
| 206 | const auto end_index = line.find('\"', 10); | 208 | const auto end_index = patch_line.find('\"', 10); |
| 207 | if (end_index == std::string::npos || end_index < 10) | 209 | if (end_index == std::string::npos || end_index < 10) |
| 208 | return; | 210 | return; |
| 209 | auto value = line.substr(10, end_index - 10); | 211 | auto value = patch_line.substr(10, end_index - 10); |
| 210 | value = EscapeStringSequences(value); | 212 | value = EscapeStringSequences(value); |
| 211 | replace.reserve(value.size()); | 213 | replace.reserve(value.size()); |
| 212 | std::copy(value.begin(), value.end(), std::back_inserter(replace)); | 214 | std::copy(value.begin(), value.end(), std::back_inserter(replace)); |
| 213 | } else { | 215 | } else { |
| 214 | // hex replacement | 216 | // hex replacement |
| 215 | const auto value = line.substr(9); | 217 | const auto value = patch_line.substr(9); |
| 216 | replace.reserve(value.size() / 2); | 218 | replace.reserve(value.size() / 2); |
| 217 | replace = Common::HexStringToVector(value, is_little_endian); | 219 | replace = Common::HexStringToVector(value, is_little_endian); |
| 218 | } | 220 | } |
| @@ -224,7 +226,7 @@ void IPSwitchCompiler::Parse() { | |||
| 224 | patch_text->GetName(), offset, Common::HexVectorToString(replace)); | 226 | patch_text->GetName(), offset, Common::HexVectorToString(replace)); |
| 225 | } | 227 | } |
| 226 | 228 | ||
| 227 | patch.records.emplace(offset, replace); | 229 | patch.records.emplace(offset, std::move(replace)); |
| 228 | } | 230 | } |
| 229 | 231 | ||
| 230 | patches.push_back(std::move(patch)); | 232 | patches.push_back(std::move(patch)); |
diff --git a/src/core/file_sys/ips_layer.h b/src/core/file_sys/ips_layer.h index 847e9bf3c..b07cc5673 100644 --- a/src/core/file_sys/ips_layer.h +++ b/src/core/file_sys/ips_layer.h | |||
| @@ -15,6 +15,8 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips); | |||
| 15 | class IPSwitchCompiler { | 15 | class IPSwitchCompiler { |
| 16 | public: | 16 | public: |
| 17 | explicit IPSwitchCompiler(VirtualFile patch_text); | 17 | explicit IPSwitchCompiler(VirtualFile patch_text); |
| 18 | ~IPSwitchCompiler(); | ||
| 19 | |||
| 18 | std::array<u8, 0x20> GetBuildID() const; | 20 | std::array<u8, 0x20> GetBuildID() const; |
| 19 | bool IsValid() const; | 21 | bool IsValid() const; |
| 20 | VirtualFile Apply(const VirtualFile& in) const; | 22 | VirtualFile Apply(const VirtualFile& in) const; |
| @@ -22,7 +24,7 @@ public: | |||
| 22 | private: | 24 | private: |
| 23 | void Parse(); | 25 | void Parse(); |
| 24 | 26 | ||
| 25 | bool valid; | 27 | bool valid = false; |
| 26 | 28 | ||
| 27 | struct IPSwitchPatch { | 29 | struct IPSwitchPatch { |
| 28 | std::string name; | 30 | std::string name; |
| @@ -32,11 +34,11 @@ private: | |||
| 32 | 34 | ||
| 33 | VirtualFile patch_text; | 35 | VirtualFile patch_text; |
| 34 | std::vector<IPSwitchPatch> patches; | 36 | std::vector<IPSwitchPatch> patches; |
| 35 | std::array<u8, 0x20> nso_build_id; | 37 | std::array<u8, 0x20> nso_build_id{}; |
| 36 | bool is_little_endian; | 38 | bool is_little_endian = false; |
| 37 | s64 offset_shift; | 39 | s64 offset_shift = 0; |
| 38 | bool print_values; | 40 | bool print_values = false; |
| 39 | std::string last_comment; | 41 | std::string last_comment = ""; |
| 40 | }; | 42 | }; |
| 41 | 43 | ||
| 42 | } // namespace FileSys | 44 | } // namespace FileSys |
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index f148e7719..03df24906 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -273,11 +273,13 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam | |||
| 273 | if (mod_dir != nullptr && mod_dir->GetSize() > 0) { | 273 | if (mod_dir != nullptr && mod_dir->GetSize() > 0) { |
| 274 | for (const auto& mod : mod_dir->GetSubdirectories()) { | 274 | for (const auto& mod : mod_dir->GetSubdirectories()) { |
| 275 | std::string types; | 275 | std::string types; |
| 276 | if (IsDirValidAndNonEmpty(mod->GetSubdirectory("exefs"))) { | 276 | |
| 277 | const auto exefs_dir = mod->GetSubdirectory("exefs"); | ||
| 278 | if (IsDirValidAndNonEmpty(exefs_dir)) { | ||
| 277 | bool ips = false; | 279 | bool ips = false; |
| 278 | bool ipswitch = false; | 280 | bool ipswitch = false; |
| 279 | 281 | ||
| 280 | for (const auto& file : mod->GetSubdirectory("exefs")->GetFiles()) { | 282 | for (const auto& file : exefs_dir->GetFiles()) { |
| 281 | if (file->GetExtension() == "ips") | 283 | if (file->GetExtension() == "ips") |
| 282 | ips = true; | 284 | ips = true; |
| 283 | else if (file->GetExtension() == "pchtxt") | 285 | else if (file->GetExtension() == "pchtxt") |