diff options
Diffstat (limited to 'src/core/file_sys')
| -rw-r--r-- | src/core/file_sys/ips_layer.cpp | 75 | ||||
| -rw-r--r-- | src/core/file_sys/ips_layer.h | 11 | ||||
| -rw-r--r-- | src/core/file_sys/patch_manager.cpp | 15 | ||||
| -rw-r--r-- | src/core/file_sys/patch_manager.h | 5 |
4 files changed, 72 insertions, 34 deletions
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp index 0cadbc375..554eae9bc 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; } @@ -76,23 +107,32 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) { return nullptr; if (real_offset + rle_size > in_data.size()) - rle_size = in_data.size() - real_offset; + rle_size = static_cast<u16>(in_data.size() - real_offset); std::memset(in_data.data() + real_offset, data.get(), rle_size); } else { // Standard Patch auto read = data_size; if (real_offset + read > in_data.size()) - read = in_data.size() - real_offset; + read = static_cast<u16>(in_data.size() - real_offset); if (ips->Read(in_data.data() + real_offset, read, offset) != data_size) return nullptr; offset += data_size; } } - 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(); } @@ -225,7 +265,7 @@ void IPSwitchCompiler::Parse() { if (patch_line.length() < 11) break; auto offset = std::stoul(patch_line.substr(0, 8), nullptr, 16); - offset += offset_shift; + offset += static_cast<unsigned long>(offset_shift); std::vector<u8> replace; // 9 - first char of replacement val @@ -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{}; diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index b14d7cb0a..019caebe9 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -345,23 +345,22 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam return out; } -std::pair<std::shared_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const { +std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const { const auto& installed{Service::FileSystem::GetUnionContents()}; const auto base_control_nca = installed->GetEntry(title_id, ContentRecordType::Control); if (base_control_nca == nullptr) return {}; - return ParseControlNCA(base_control_nca); + return ParseControlNCA(*base_control_nca); } -std::pair<std::shared_ptr<NACP>, VirtualFile> PatchManager::ParseControlNCA( - const std::shared_ptr<NCA>& nca) const { - const auto base_romfs = nca->GetRomFS(); +std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::ParseControlNCA(const NCA& nca) const { + const auto base_romfs = nca.GetRomFS(); if (base_romfs == nullptr) return {}; - const auto romfs = PatchRomFS(base_romfs, nca->GetBaseIVFCOffset(), ContentRecordType::Control); + const auto romfs = PatchRomFS(base_romfs, nca.GetBaseIVFCOffset(), ContentRecordType::Control); if (romfs == nullptr) return {}; @@ -373,7 +372,7 @@ std::pair<std::shared_ptr<NACP>, VirtualFile> PatchManager::ParseControlNCA( if (nacp_file == nullptr) nacp_file = extracted->GetFile("Control.nacp"); - const auto nacp = nacp_file == nullptr ? nullptr : std::make_shared<NACP>(nacp_file); + auto nacp = nacp_file == nullptr ? nullptr : std::make_unique<NACP>(nacp_file); VirtualFile icon_file; for (const auto& language : FileSys::LANGUAGE_NAMES) { @@ -382,6 +381,6 @@ std::pair<std::shared_ptr<NACP>, VirtualFile> PatchManager::ParseControlNCA( break; } - return {nacp, icon_file}; + return {std::move(nacp), icon_file}; } } // namespace FileSys diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index eb6fc4607..7d168837f 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -57,11 +57,10 @@ public: // Given title_id of the program, attempts to get the control data of the update and parse it, // falling back to the base control data. - std::pair<std::shared_ptr<NACP>, VirtualFile> GetControlMetadata() const; + std::pair<std::unique_ptr<NACP>, VirtualFile> GetControlMetadata() const; // Version of GetControlMetadata that takes an arbitrary NCA - std::pair<std::shared_ptr<NACP>, VirtualFile> ParseControlNCA( - const std::shared_ptr<NCA>& nca) const; + std::pair<std::unique_ptr<NACP>, VirtualFile> ParseControlNCA(const NCA& nca) const; private: u64 title_id; |
